RefundController.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <?php
  2. namespace App\Http\Controllers;
  3. use App\Events\AuthRefundTip;
  4. use App\Models\Address;
  5. use App\Models\DwbsUser;
  6. use App\Models\Goods;
  7. use App\Models\Order;
  8. use App\Models\OrderCancel;
  9. use App\Models\OrderRefund;
  10. use App\Models\OrderDetail;
  11. use App\Models\Store;
  12. use App\Models\User;
  13. use Illuminate\Http\Request;
  14. use Illuminate\Support\Facades\Auth;
  15. use Illuminate\Support\Facades\DB;
  16. use Illuminate\Support\Facades\Storage;
  17. class RefundController extends Controller
  18. {
  19. //获取退款订单原始信息
  20. public function getOriginOrderInfo(Request $request)
  21. {
  22. $order_no=$request->input('order_no');
  23. $data=Order::with(['address','cancel'=>function($query){$query->where('using',1);},'store:id,name,img,phone']);
  24. $order=$data->where('order_no',$order_no)->first()->toArray();
  25. if(empty($order)){
  26. return $this->error('450001','订单不存在');
  27. }
  28. $goods_ids=OrderDetail::where('order_no',$order['order_no'])->groupBy('goods_id')->pluck('goods_id');
  29. $goods=[];
  30. foreach($goods_ids as $key=>$val){
  31. $goods[$val]=Goods::select('id','name','img','main_attr')->where('id',$val)->first()->toArray();
  32. $order_details=OrderDetail::where('order_no',$order['order_no'])->where('goods_id',$val)->get()->toArray();
  33. if(count($order_details)>0){
  34. $sku=[];
  35. foreach($order_details as $k=>$v){
  36. $sku[$v['sku_id']]=$v;
  37. }
  38. $goods[$val]['sku']=$sku;
  39. $goods[$val]['price']=$order_details[0]['price'];
  40. }
  41. }
  42. $order['goods']=$goods;
  43. $refund_nos=OrderRefund::where('order_no',$order_no)->whereIn('status',[0,1,3])->pluck('refund_no');
  44. $refund_goods_ids=OrderDetail::whereIn('order_no',$refund_nos)->groupBy('goods_id')->pluck('goods_id');
  45. $refunds=[];
  46. foreach($refund_goods_ids as $key=>$val){
  47. $refunds[$val]=Goods::select('id','name','img','main_attr')->where('id',$val)->first()->toArray();
  48. $refunds_details=OrderDetail::select('goods_id','sku_id','type','size',DB::raw('sum(num) as num'))
  49. ->whereIn('order_no',$refund_nos)->where('goods_id',$val)->groupBy('sku_id')->get()->toArray();
  50. if(count($refunds_details)>0){
  51. $sku=[];
  52. foreach($refunds_details as $k=>$v){
  53. $sku[$v['sku_id']]=$v;
  54. }
  55. $refunds[$val]['sku']=$sku;
  56. }
  57. }
  58. $order['refunds']=$refunds;
  59. $products=[];
  60. foreach($goods as $key=>$val){
  61. $products[$key]= $goods[$key];
  62. $sku=[];
  63. foreach($val['sku'] as $k=>$v){
  64. if(empty($refunds[$key]['sku'][$k])){
  65. unset($products[$key]['sku']);
  66. $sku[$k]= $goods[$key]['sku'][$k];
  67. }else{
  68. if($goods[$key]['sku'][$k]['num'] > $refunds[$key]['sku'][$k]['num']){
  69. unset($products[$key]['sku']);
  70. $sku[$k] = $goods[$key]['sku'][$k];
  71. $sku[$k]['num']=$goods[$key]['sku'][$k]['num'] - $refunds[$key]['sku'][$k]['num'];
  72. }else{
  73. unset($products[$key]['sku']);
  74. }
  75. }
  76. }
  77. $products[$key]['sku']= $sku;
  78. if(empty($products[$key]['sku'])){
  79. unset($products[$key]);
  80. }
  81. }
  82. $order['products']=$products;
  83. return $this->success($order);
  84. }
  85. //提交退货订单
  86. public function submitRefundOrder(Request $request)
  87. {
  88. $sku = $request->input('sku');
  89. $reason = $request->input('reason');
  90. $reason_all = $request->input('reason_all');
  91. $img = $request->input('img');
  92. $origin_order_no=$request->input('origin_order_no');
  93. $origin_order=Order::where('order_no',$origin_order_no)->first();
  94. if($origin_order->is_refund==1){
  95. return $this->error('450001','该订单存在正在审核中的退货订单');
  96. }
  97. if($origin_order->is_refund==3){
  98. return $this->error('450001','该订单已全部退货');
  99. }
  100. $refund_no=Order::order_no('th');
  101. $account = $total = 0;
  102. $list = $sku_ids = [];
  103. foreach($sku as $key=>$val){
  104. if($val[1] > 0){
  105. $order_detail=OrderDetail::with(['goods'])->where('id',$val[0])->first();
  106. if($order_detail->num < $val[1]){
  107. $num = $order_detail->num;
  108. }else{
  109. $num = $val[1];
  110. }
  111. $list[$key]['num']=$num;
  112. $list[$key]['price']=$order_detail->price;
  113. $list[$key]['account']=$order_detail->price * $num;
  114. $list[$key]['order_no']=$refund_no;
  115. $list[$key]['goods_id']=$order_detail->goods_id;
  116. $list[$key]['sku_id']=$order_detail->sku_id;
  117. $list[$key]['size']=$order_detail->size;
  118. $list[$key]['type']=$order_detail->type;
  119. $list[$key]['style']=2;
  120. $list[$key]['created_at']=date("Y-m-d H:i:s");
  121. $list[$key]['updated_at']=date("Y-m-d H:i:s");
  122. $total += $num;
  123. $account += $order_detail->price * $num;
  124. }
  125. }
  126. $data=[
  127. 'refund_no'=>$refund_no,
  128. 'order_no'=>$origin_order_no,
  129. 'store_id'=>$origin_order->store_id,
  130. 'user_id'=>$origin_order->user_id,
  131. 'reason'=>$reason,
  132. 'reason_all'=>$reason_all,
  133. 'total'=>$total,
  134. 'account'=>$account,
  135. 'img'=>json_encode($img),
  136. 'status'=>0,
  137. 'op_name'=>Auth::user()->nickname,
  138. 'op_type'=>1,
  139. 'remark'=>null,
  140. ];
  141. try{
  142. DB::transaction(function ()use($list,$data,$origin_order_no){
  143. OrderDetail::insert($list);
  144. OrderRefund::create($data);
  145. Order::where('order_no',$origin_order_no)->update(['is_refund'=>1]);
  146. },5);
  147. //申请退货提醒
  148. $store=Store::where('id',$origin_order->store_id)->first();
  149. $user=DwbsUser::withTrashed()->where('id',$store->user_id)->first();
  150. if($user->openid){
  151. $data['openid']=$user->openid;
  152. $data['data']=[
  153. 'first' => '您的客户提交了新的退货信息',
  154. 'keyword1' => $origin_order->order_no,
  155. 'keyword2' => '客户退货',
  156. ];
  157. event(new AuthRefundTip($data));
  158. }
  159. return $this->success($refund_no);
  160. }catch(\Exception $e){
  161. return $this->error('450001',$e->getMessage());
  162. }
  163. }
  164. //取消退货审核
  165. public function cancelRefundOrder(Request $request){
  166. $refund_id=$request->input('refund_id');
  167. $refund=OrderRefund::where('id',$refund_id)->first();
  168. if(empty($refund)){
  169. return $this->error('450001','退货单不存在');
  170. }
  171. if($refund->status==1){
  172. return $this->error('450001','已成功退货,不能取消');
  173. }
  174. if($refund->status==2){
  175. return $this->error('450001','退货申请已被驳回,不能取消');
  176. }
  177. try{
  178. DB::transaction(function()use($refund){
  179. OrderRefund::where('id',$refund->id)->delete();
  180. $auth_count=OrderRefund::where('order_no',$refund->order_no)->where('status',0)->count();
  181. if($auth_count>=1){
  182. Order::where('order_no',$refund->order_no)->update([
  183. 'is_refund'=>1
  184. ]);
  185. }else{
  186. $count=OrderRefund::where('order_no',$refund->order_no)->where('status',1)->count();
  187. if($count>=1){
  188. Order::where('order_no',$refund->order_no)->update([
  189. 'is_refund'=>2
  190. ]);
  191. }else{
  192. Order::where('order_no',$refund->order_no)->update([
  193. 'is_refund'=>0
  194. ]);
  195. }
  196. }
  197. },5);
  198. return $this->success([]);
  199. }catch(\Exception $e){
  200. return $this->error('450001',$e->getMessage());
  201. }
  202. }
  203. //获取用户端所有退货订单
  204. public function getAllRefundOrder(Request $request)
  205. {
  206. $user_id=Auth::user()->id;
  207. $page_index=$request->input('page_index');
  208. $page_size=$request->input('page_size');
  209. $num=$page_size*($page_index-1);
  210. $refund_no=$request->input('refund_no');
  211. $data=OrderRefund::with('store:id,name,phone')->where('user_id',$user_id);
  212. if($refund_no){
  213. $data->where('refund_no','like','%'.$refund_no.'%');
  214. }
  215. $total= $data->count();
  216. $refunds = $data->orderBy('id','desc')->skip($num)->take($page_size)->get();
  217. foreach($refunds as $key=>$val){
  218. $goods=[];
  219. $goods_ids=OrderDetail::where('order_no',$val->refund_no)->groupBy('goods_id')->pluck('goods_id');
  220. foreach($goods_ids as $k=>$v){
  221. $goods[$k]=Goods::where('id',$v)->first();
  222. $goods[$k]->sku=OrderDetail::where('order_no',$val->refund_no)->where('goods_id',$v)->get();
  223. }
  224. $refunds[$key]->goods=$goods;
  225. }
  226. return $this->success_list($refunds,'成功',$total);
  227. }
  228. //获取用户端退货订单详情
  229. public function getRefundOrderDetail(Request $request)
  230. {
  231. $refund_id = $request->input('refund_id');
  232. //获取订单信息(id)
  233. $order = OrderRefund::with(['store:id,name,img,phone'])->where('id', $refund_id)->first();
  234. $goods_ids = OrderDetail::where('order_no', $order->refund_no)->groupBy('goods_id')->pluck('goods_id');
  235. $goods = [];
  236. foreach ($goods_ids as $key => $val) {
  237. $goods[$key] = Goods::where('id', $val)->first();
  238. $goods[$key]->sku = OrderDetail::where('order_no', $order->refund_no)->where('goods_id', $val)->get();
  239. }
  240. $order->goods = $goods;
  241. return $this->success($order);
  242. }
  243. //删除订单
  244. public function deleteOriginOrder(Request $request){
  245. $order_no=$request->input('order_no');
  246. $res=Order::where('order_no',$order_no)->delete();
  247. if($res){
  248. return $this->success([]);
  249. }else{
  250. return $this->error();
  251. }
  252. }
  253. //上传图片
  254. public function uploadRefundOrderImg(Request $request){
  255. $path_url = 'public/refund';
  256. $path = $request->file('img')->store($path_url);
  257. if($path){
  258. $url = env('APP_URL').Storage::url($path);
  259. return $this->success($url);
  260. }
  261. return $this->error();
  262. }
  263. function createNoncestr($length =32)
  264. {
  265. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  266. $str ="";
  267. for ( $i = 0; $i < $length; $i++ ) {
  268. $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  269. }
  270. return $str;
  271. }
  272. function unicode() {
  273. $str = uniqid(mt_rand(),1);
  274. $str=sha1($str);
  275. return md5($str);
  276. }
  277. function arraytoxml($data){
  278. $str='<xml>';
  279. foreach($data as $k=>$v) {
  280. $str.='<'.$k.'>'.$v.'</'.$k.'>';
  281. }
  282. $str.='</xml>';
  283. return $str;
  284. }
  285. function xmltoarray($xml) {
  286. //禁止引用外部xml实体
  287. libxml_disable_entity_loader(true);
  288. $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
  289. $val = json_decode(json_encode($xmlstring),true);
  290. return $val;
  291. }
  292. function curl($param="",$url) {
  293. $postUrl = $url;
  294. $curlPost = $param;
  295. $ch = curl_init(); //初始化curl
  296. curl_setopt($ch, CURLOPT_URL,$postUrl); //抓取指定网页
  297. curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
  298. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
  299. curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
  300. curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); // 增加 HTTP Header(头)里的字段
  301. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 终止从服务端进行验证
  302. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  303. curl_setopt($ch,CURLOPT_SSLCERT,config('wechat.payment.default.cert_path')); //这个是证书的位置绝对路径cert_path
  304. curl_setopt($ch,CURLOPT_SSLKEY,config('wechat.payment.default.key_path')); //这个也是证书的位置绝对路径
  305. $data = curl_exec($ch); //运行curl
  306. curl_close($ch);
  307. return $data;
  308. }
  309. /*
  310. $amount 发送的金额(分)目前发送金额不能少于1元
  311. $re_openid, 发送人的 openid
  312. $desc // 企业付款描述信息 (必填)
  313. $check_name 收款用户姓名 (选填)
  314. */
  315. public function sendMoney($desc='测试',$check_name=''){
  316. $data=array(
  317. 'mch_appid'=>config('wechat.payment.default.app_id'),//商户账号appid
  318. 'mchid'=> "1604585534",//商户号
  319. 'nonce_str'=>$this->createNoncestr(),//随机字符串
  320. // 'partner_trade_no'=> date('YmdHis').rand(1000, 9999),//商户订单号
  321. 'partner_trade_no'=> 'CP202101290000000000001',//商户订单号
  322. 'openid'=> 'oJn4Fv3GoK8rMqftML5kSU8FoDUc',//用户openid
  323. 'check_name'=>'NO_CHECK',//校验用户姓名选项,
  324. // 're_user_name'=> $check_name,//收款用户姓名
  325. 'amount'=> 1,//金额
  326. 'desc'=> $desc,//企业付款描述信息
  327. 'spbill_create_ip'=> $_SERVER['REMOTE_ADDR'],//Ip地址
  328. );
  329. $secrect_key=config('wechat.payment.default.key');///这个就是个API密码。MD5 32位。
  330. $data=array_filter($data);
  331. ksort($data);
  332. $str='';
  333. foreach($data as $k=>$v) {
  334. $str.=$k.'='.$v.'&';
  335. }
  336. $str.='key='.$secrect_key;
  337. $data['sign']=md5($str);
  338. $xml=$this->arraytoxml($data);
  339. $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //调用接口
  340. $res=$this->curl($xml,$url);
  341. $return=$this->xmltoarray($res);
  342. return $return;
  343. print_r($return);
  344. //返回来的结果
  345. // [return_code] => SUCCESS [return_msg] => Array ( ) [mch_appid] => wxd44b890e61f72c63 [mchid] => 1493475512 [nonce_str] => 616615516 [result_code] => SUCCESS [partner_trade_no] => 20186505080216815
  346. // [payment_no] => 1000018361251805057502564679 [payment_time] => 2018-05-15 15:29:50
  347. $responseObj = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
  348. echo $res= $responseObj->return_code; //SUCCESS 如果返回来SUCCESS,则发生成功,处理自己的逻辑
  349. return $res;
  350. }
  351. }