<?php /** * Created by PhpStorm. * User: ruidiudiu * Date: 2018/11/24 * Time: 8:54 */ namespace app\portal\controller; use cmf\controller\HomeBaseController; use think\Db; use wxapp\pay\WeixinPay; /** * @title 订单相关接口 * @description 订单相关接口 * @group 订单相关接口 */ class OrderController extends HomeBaseController{ // /** // * @title 生成订单 // * @description 生成订单,加入开始时间和用户id // * @author 董瑞恩 // * @url /portal/order/createOrder // * @method GET // * // * @param name:users_id type:String require:1 default:无 other: desc:用户id // * @param name:name type:String require:1 default:无 other: desc:设备名称 // * // */ public function createOrder($users_id,$name){ $order=[ 'order_no' => cmf_get_order_sn(), 'eq_name' => $name, 'users_id' => $users_id, 'start_time' => time(), 'state' => 1 ]; try{ Db::startTrans(); Db::name('users')->where('id',$users_id)->update(['is_use'=>1]); Db::name('order')->insert($order); }catch (\Exception $exception){ Db::rollback(); $data=[ 'state'=>false, 'message'=>$exception->getMessage() ]; return $data; } Db::commit(); $data=[ 'state'=>true, 'order_no' => $order['order_no'] ]; return $data; } // /** // * @title 完成订单 // * @description 订单完成,加入结束时间和结算费用,并调用微信统一下单 // * @author 董瑞恩 // * @url /portal/order/order // * @method GET // * // * @param name:users_id type:String require:1 default:无 other: desc:用户id // * // * @return data:返回用于调用支付的参数 // */ public function order($users_id,$name){ $order= Db::name('order')->where(['users_id'=>$users_id,'state'=>1])->find(); $end_time=time(); $price=$this->getPrice($users_id,$order['start_time'],$end_time); $time=ceil(($end_time-$order['start_time'])/3600); $data=[ 'end_time'=>$end_time, 'time' => $time, 'price' => $price, 'state' => 2 ]; try{ Db::startTrans(); Db::name('users')->where('id',$users_id)->update(['is_use'=>0]); Db::name('equipment')->where('name',$name)->update(['use'=>0]); Db::name('order')->where('order_no',$order['order_no'])->update($data); }catch (\Exception $exception){ Db::rollback(); $data=[ 'state'=>false, 'message'=>'数据库操作失败', 'error' =>$exception->getMessage() ]; $this->apiResponse(200,'success',$data); } Db::commit(); //调起支付 if ($price==0){ try{ Db::name('order')->where(['order_no'=>$order['order_no']])->update(['state'=>3]); }catch (\Exception $exception){ $this->apiResponse(301,'error:'.$exception->getMessage()); } $data=[ 'state'=>2, ]; $this->apiResponse(200,'success',$data); } $this->pay($order['order_no']); } public function getPrice($users_id=3,$start_time=1543472707,$end_time=1543481349){ $cost=Db::name('cost')->where('id',1)->find(); $interval = Db::name('interval')->where('id',1)->find(); $is_free=Db::name('users')->where('id',$users_id)->find()['is_free']; $free=$cost['free']; //获取整天的价格 $dayPrice=$this->getDayPrice(); dump(date('Y-m-d H:i:s',$start_time)); dump(date('Y-m-d H:i:s',$end_time)); //用了多少天 $day=floor(($end_time-$start_time)/86400); $dayPrice=$day*$dayPrice; //去掉整天的金额 $new_start_time=$start_time+$day*86400;//时间戳 $new_end_time= $end_time;//时间戳 $hours_start_time=date('His',$new_start_time); $hours_end_time=date('His',$new_end_time); $stateTime=strtotime($interval['start_time']); $endTime=strtotime($interval['end_time']); //判断预设时间段是否跨天 $price=0; if ($endTime < $stateTime){ //设备使用时间段是否跨天(不跨天) if ($hours_end_time > $hours_start_time){ //在预设时间段左边并不与之重合 if (($new_start_time > strtotime('00:00:00') && $new_start_time < $endTime) && ($new_end_time > $new_start_time && $new_end_time < $endTime)){ dump('1'); $price +=(ceil(($new_end_time-$new_start_time)/3600) * $interval['price']); } //与预设时间段的尾部重合 if (($new_start_time > strtotime('00:00:00') && $new_start_time < $endTime) && ($new_end_time > $endTime && $new_end_time < $stateTime)){ dump('2'); $price +=(ceil(($endTime-$new_start_time)/3600) * $interval['price'] + ceil(($new_end_time-$endTime)/3600) * $cost['cost']); } //与预设时间段的头尾都重合 if (($new_start_time > strtotime('00:00:00') && $new_start_time < $endTime) && $new_end_time > $stateTime){ dump('3'); $price +=(ceil(($endTime-$new_start_time)/3600) * $interval['price'] + ceil(($new_end_time-$stateTime)/3600) * $interval['price'] + ceil(($stateTime-$endTime)/3600) * $cost['cost']); } //不与预设时间段重合 if (($new_start_time > $endTime && $new_start_time < $stateTime) && ($new_end_time < $new_start_time && $new_end_time < $stateTime)){ //存在首小时免费 dump('4'); $price +=(ceil(($new_end_time-$new_start_time)/3600) * $cost['cost']); if ($free==1 && $is_free==0){ $price-=$cost['cost']; Db::name('users')->where('id',$users_id)->update(['is_free'=>1]); } } //与预设时间段的头部重合 if (($new_start_time > $endTime && $new_start_time < $stateTime) && ($new_end_time > $stateTime && $new_end_time < strtotime('24:00:00'))){ //存在首小时免费 dump('5'); $price += (ceil(($stateTime-$new_start_time)/3600) * $cost['cost'] + ceil(($new_end_time-$stateTime)/3600) * $interval['price']); if ($free==1 && $is_free==0){ $price-=$cost['cost']; Db::name('users')->where('id',$users_id)->update(['is_free'=>1]); } } //在预设时间段右边并不与之重合 if (($new_start_time > $stateTime && $new_start_time < strtotime('24:00:00')) && ($new_end_time > $new_start_time && $new_end_time < strtotime('24:00:00'))){ dump('6'); $price +=(ceil(($new_end_time-$new_start_time)/3600) * $interval['price']); } dump('什么都没有'); //设备使用时间段是否跨天(跨天:开始时间在昨天,结束时间在今天) }else{ $YesterdayStateTime=$stateTime-86400; $YesterdayEndTime=$endTime-86400; //昨天预设结束前使用,今天预设结束前停止 if(($new_start_time > (strtotime('00:00:00')-86400) && $new_start_time < $YesterdayEndTime) && ($new_end_time > strtotime('00:00:00') && $new_end_time < $endTime)){ echo 1; $price+= ceil(($YesterdayEndTime-$new_start_time)/3600) * $interval['price'] +ceil(($YesterdayStateTime-$YesterdayEndTime)/3600) * $cost['cost'] +ceil(($new_end_time-$YesterdayStateTime)/3600) * $interval['price']; } //昨天预设开始前使用,今天预设结束前停止 if(($new_start_time > $YesterdayEndTime && $new_start_time < $YesterdayStateTime) && ($new_end_time > strtotime('00:00:00') && $new_end_time < $endTime)){ //存在首小时免费 echo 1; $price+= ceil(($YesterdayStateTime-$new_start_time)/3600) * $cost['cost'] +ceil(($new_end_time-$YesterdayStateTime)/3600) * $interval['price']; if ($free==1 && $is_free==0){ $price-=$cost['cost']; Db::name('users')->where('id',$users_id)->update(['is_free'=>1]); } } //昨天预设开始前使用,今天预设结束后停止 if(($new_start_time > $YesterdayEndTime && $new_start_time < $YesterdayStateTime) && ($new_end_time > $endTime && $new_end_time < $stateTime)){ //存在首小时免费 echo 1; $price+= ceil(($YesterdayStateTime-$new_start_time)/3600) * $cost['cost'] +ceil(($endTime-$YesterdayStateTime)/3600) * $interval['price'] +ceil(($new_end_time-$endTime)/3600) * $cost['cost']; if ($free==1 && $is_free==0){ $price-=$cost['cost']; Db::name('users')->where('id',$users_id)->update(['is_free'=>1]); } } //昨天预设开始后使用,今天预设结束前停止 if(($new_start_time > $YesterdayStateTime && $new_start_time < strtotime('00:00:00')) && ($new_end_time > strtotime('00:00:00') && $new_end_time < $endTime)){ echo 1; $price+= ceil(($new_end_time-$new_start_time)/3600) * $interval['price']; } //昨天预设开始后使用,今天预设结束后停止 if(($new_start_time > $YesterdayStateTime && $new_start_time < strtotime('00:00:00')) && ($new_end_time > $endTime && $new_end_time < $stateTime)){ echo 1; $price+= ceil(($endTime-$new_start_time)/3600) * $interval['price'] +ceil(($new_end_time-$endTime)/3600) * $cost['cost']; } //昨天预设开始后使用,今天预设开始前停止 if(($new_start_time > $YesterdayStateTime && $new_start_time < strtotime('00:00:00')) && ($new_end_time > $stateTime && $new_end_time < ($new_start_time+86400))){ echo 1; $price+= ceil(($endTime-$new_start_time)/3600) * $interval['price'] +ceil(($stateTime-$endTime)/3600) * $cost['cost'] +ceil(($new_end_time-$stateTime)/3600) * $interval['price']; } } } if ($price > $cost['ceiling']){ $price = $cost['ceiling']; } $numPrice = $dayPrice+$price; return $numPrice; } //获取整天的价格 public function getDayPrice(){ $cost=Db::name('cost')->where('id',1)->find(); $interval = Db::name('interval')->where('id',1)->find(); $stateTime=strtotime($interval['start_time']); $endTime=strtotime($interval['end_time']); //预设时间长度 $time=($stateTime-$endTime)/3600; if ($endTime < $stateTime){ $price=($time * $cost['cost']) + ((24-$time) * $interval['price']); }else{ $price=($time * $interval['price']) + ((24-$time) * $cost['cost']); } if ($price > $cost['ceiling']){ $price = $cost['ceiling']; } return $price; } /** * @title 统一下单 * @description 微信统一下单 * @author 董瑞恩 * @url /portal/order/pay * @method GET * * @param name:order_no type:String require:1 default:无 other: desc:订单号 * * @return data:返回用于调用支付的参数 */ public function pay($order_no){ $order=Db::name('order')->where(['order_no'=>$order_no,'state'=>2])->find(); $openId=Db::name('users')->where('id',$order['users_id'])->find()['open_id']; $body='支付'; $price=$order['price']*1;//订单价格 $notify_url=url('order/notify','','',true);//回调地址 $out_trade_no=$order_no.$this->create_noncestr(4); $wxPay=new WeixinPay($openId,$out_trade_no,$body,$price,$notify_url); $pay=$wxPay->pay(); if (isset($pay['package'])){ $data=[ 'state'=>1, 'pay'=>$pay ]; $this->apiResponse(200,'success',$data); }else{ $data=[ 'state'=>0, 'message'=>'统一下单失败', 'error' => $pay ]; $this->apiResponse(200,'success',$data); } } //支付回调接口 public function notify(){ $param = $this->request->param(); if ($param == null) { $param = file_get_contents("php://input"); if ($param == null) { $param = $GLOBALS['HTTP_RAW_POST_DATA']; } } $wxPay=new WeixinPay(); $data = $wxPay->xmlToArray($param); $Sign = $data['sign']; //支付成功回调后变更订单状态 $mySign = $wxPay->getSign($data); $order_no =substr($data['out_trade_no'], 0, -4); if ($Sign===$mySign && $data['return_code'] == 'SUCCESS') { try{ Db::name('order')->where(['order_no'=>$order_no])->update(['state'=>3]); }catch (\Exception $exception){ $this->apiResponse(301,'error:'.$exception->getMessage()); } return "<xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> </xml>"; } } function create_noncestr($length = 4){ $chars = "0123456789"; $str = ""; for($i=0;$i<$length;$i++){ $str.= substr($chars,mt_rand(0,strlen($chars)-1),1); } return $str; } }