审查视图

app/portal/controller/OrderController.php 14.3 KB
董瑞恩 authored
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
<?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{
董瑞恩 authored
23 24 25 26 27 28 29 30 31 32 33 34
//    /**
//     * @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){
董瑞恩 authored
35 36
        $order=[
            'order_no' => cmf_get_order_sn(),
董瑞恩 authored
37
            'eq_name' => $name,
董瑞恩 authored
38 39 40 41 42 43
            'users_id' => $users_id,
            'start_time' => time(),
            'state' => 1
        ];
        try{
            Db::startTrans();
董瑞恩 authored
44
            Db::name('users')->where('id',$users_id)->update(['is_use'=>1]);
董瑞恩 authored
45 46 47
            Db::name('order')->insert($order);
        }catch (\Exception $exception){
            Db::rollback();
董瑞恩 authored
48 49
            $data=[
                'state'=>false,
董瑞恩 authored
50
                'message'=>$exception->getMessage()
董瑞恩 authored
51
            ];
董瑞恩 authored
52
            return $data;
董瑞恩 authored
53 54
        }
        Db::commit();
董瑞恩 authored
55 56 57 58 59
        $data=[
            'state'=>true,
            'order_no' => $order['order_no']
        ];
        return $data;
董瑞恩 authored
60 61
    }
董瑞恩 authored
62 63 64 65 66 67 68 69 70 71 72 73 74
//    /**
//     * @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();
董瑞恩 authored
75
        $end_time=time();
董瑞恩 authored
76
        $price=$this->getPrice($users_id,$order['start_time'],$end_time);
董瑞恩 authored
77
        $time=ceil(($end_time-$order['start_time'])/3600);
董瑞恩 authored
78 79
        $data=[
            'end_time'=>$end_time,
董瑞恩 authored
80
            'time' => $time,
董瑞恩 authored
81 82 83 84 85
            'price' => $price,
            'state' => 2
        ];
        try{
            Db::startTrans();
董瑞恩 authored
86
            Db::name('users')->where('id',$users_id)->update(['is_use'=>0]);
董瑞恩 authored
87 88
            Db::name('equipment')->where('name',$name)->update(['use'=>0]);
            Db::name('order')->where('order_no',$order['order_no'])->update($data);
董瑞恩 authored
89 90
        }catch (\Exception $exception){
            Db::rollback();
董瑞恩 authored
91 92
            $data=[
                'state'=>false,
董瑞恩 authored
93 94
                'message'=>'数据库操作失败',
                'error' =>$exception->getMessage()
董瑞恩 authored
95 96
            ];
            $this->apiResponse(200,'success',$data);
董瑞恩 authored
97 98
        }
        Db::commit();
董瑞恩 authored
99
        //调起支付
董瑞恩 authored
100
        if ($price==0){
董瑞恩 authored
101 102 103 104 105
            try{
                Db::name('order')->where(['order_no'=>$order['order_no']])->update(['state'=>3]);
            }catch (\Exception $exception){
                $this->apiResponse(301,'error:'.$exception->getMessage());
            }
董瑞恩 authored
106 107 108 109 110
            $data=[
                'state'=>2,
            ];
            $this->apiResponse(200,'success',$data);
        }
董瑞恩 authored
111
        $this->pay($order['order_no']);
董瑞恩 authored
112
董瑞恩 authored
113 114
    }
董瑞恩 authored
115
董瑞恩 authored
116
    public function getPrice($users_id=3,$start_time=1543472707,$end_time=1543481349){
董瑞恩 authored
117 118
        $cost=Db::name('cost')->where('id',1)->find();
        $interval = Db::name('interval')->where('id',1)->find();
董瑞恩 authored
119
        $is_free=Db::name('users')->where('id',$users_id)->find()['is_free'];
董瑞恩 authored
120
        $free=$cost['free'];
董瑞恩 authored
121 122 123
        //获取整天的价格
        $dayPrice=$this->getDayPrice();
董瑞恩 authored
124
董瑞恩 authored
125 126
        dump(date('Y-m-d H:i:s',$start_time));
        dump(date('Y-m-d H:i:s',$end_time));
董瑞恩 authored
127
        //用了多少天
董瑞恩 authored
128
        $day=floor(($end_time-$start_time)/86400);
董瑞恩 authored
129
        $dayPrice=$day*$dayPrice;
董瑞恩 authored
130 131
        //去掉整天的金额
        $new_start_time=$start_time+$day*86400;//时间戳
董瑞恩 authored
132
        $new_end_time= $end_time;//时间戳
董瑞恩 authored
133 134
        $hours_start_time=date('His',$new_start_time);
        $hours_end_time=date('His',$new_end_time);
董瑞恩 authored
135
董瑞恩 authored
136 137
        $stateTime=strtotime($interval['start_time']);
        $endTime=strtotime($interval['end_time']);
董瑞恩 authored
138
        //判断预设时间段是否跨天
董瑞恩 authored
139
        $price=0;
董瑞恩 authored
140
        if ($endTime < $stateTime){
董瑞恩 authored
141
            //设备使用时间段是否跨天(不跨天)
董瑞恩 authored
142
            if ($hours_end_time > $hours_start_time){
董瑞恩 authored
143 144
                //在预设时间段左边并不与之重合
                if (($new_start_time > strtotime('00:00:00') && $new_start_time < $endTime) && ($new_end_time > $new_start_time && $new_end_time < $endTime)){
董瑞恩 authored
145
                    dump('1');
董瑞恩 authored
146
                    $price +=(ceil(($new_end_time-$new_start_time)/3600) * $interval['price']);
董瑞恩 authored
147
                }
董瑞恩 authored
148 149
                //与预设时间段的尾部重合
                if (($new_start_time > strtotime('00:00:00') && $new_start_time < $endTime) && ($new_end_time > $endTime && $new_end_time < $stateTime)){
董瑞恩 authored
150
                    dump('2');
董瑞恩 authored
151
                    $price +=(ceil(($endTime-$new_start_time)/3600) * $interval['price'] +  ceil(($new_end_time-$endTime)/3600) * $cost['cost']);
董瑞恩 authored
152
                }
董瑞恩 authored
153 154
                //与预设时间段的头尾都重合
                if (($new_start_time > strtotime('00:00:00') && $new_start_time < $endTime) && $new_end_time > $stateTime){
董瑞恩 authored
155
                    dump('3');
董瑞恩 authored
156 157 158 159 160
                    $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)){
                    //存在首小时免费
董瑞恩 authored
161
                    dump('4');
董瑞恩 authored
162
                    $price +=(ceil(($new_end_time-$new_start_time)/3600) * $cost['cost']);
董瑞恩 authored
163
                    if ($free==1 && $is_free==0){
董瑞恩 authored
164
                        $price-=$cost['cost'];
董瑞恩 authored
165
                        Db::name('users')->where('id',$users_id)->update(['is_free'=>1]);
董瑞恩 authored
166
                    }
董瑞恩 authored
167
                }
董瑞恩 authored
168 169 170
                //与预设时间段的头部重合
                if (($new_start_time > $endTime && $new_start_time < $stateTime) && ($new_end_time > $stateTime && $new_end_time < strtotime('24:00:00'))){
                    //存在首小时免费
董瑞恩 authored
171
                    dump('5');
董瑞恩 authored
172
                    $price += (ceil(($stateTime-$new_start_time)/3600) * $cost['cost'] + ceil(($new_end_time-$stateTime)/3600) * $interval['price']);
董瑞恩 authored
173
                    if ($free==1 && $is_free==0){
董瑞恩 authored
174
                        $price-=$cost['cost'];
董瑞恩 authored
175
                        Db::name('users')->where('id',$users_id)->update(['is_free'=>1]);
董瑞恩 authored
176
                    }
董瑞恩 authored
177 178 179
                }
                //在预设时间段右边并不与之重合
                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'))){
董瑞恩 authored
180
                    dump('6');
董瑞恩 authored
181
                    $price +=(ceil(($new_end_time-$new_start_time)/3600) * $interval['price']);
董瑞恩 authored
182
                }
董瑞恩 authored
183
                dump('什么都没有');
董瑞恩 authored
184
            //设备使用时间段是否跨天(跨天:开始时间在昨天,结束时间在今天)
董瑞恩 authored
185
            }else{
董瑞恩 authored
186 187
                $YesterdayStateTime=$stateTime-86400;
                $YesterdayEndTime=$endTime-86400;
董瑞恩 authored
188
                //昨天预设结束前使用,今天预设结束前停止
董瑞恩 authored
189
                if(($new_start_time > (strtotime('00:00:00')-86400) && $new_start_time < $YesterdayEndTime) && ($new_end_time > strtotime('00:00:00') && $new_end_time < $endTime)){
董瑞恩 authored
190
                    echo 1;
董瑞恩 authored
191 192 193
                    $price+= ceil(($YesterdayEndTime-$new_start_time)/3600) * $interval['price']
                            +ceil(($YesterdayStateTime-$YesterdayEndTime)/3600) * $cost['cost']
                            +ceil(($new_end_time-$YesterdayStateTime)/3600) * $interval['price'];
董瑞恩 authored
194
                }
董瑞恩 authored
195
                //昨天预设开始前使用,今天预设结束前停止
董瑞恩 authored
196 197
                if(($new_start_time > $YesterdayEndTime && $new_start_time < $YesterdayStateTime) && ($new_end_time > strtotime('00:00:00') && $new_end_time < $endTime)){
                    //存在首小时免费
董瑞恩 authored
198
                    echo 1;
董瑞恩 authored
199 200
                    $price+= ceil(($YesterdayStateTime-$new_start_time)/3600) *  $cost['cost']
                            +ceil(($new_end_time-$YesterdayStateTime)/3600) * $interval['price'];
董瑞恩 authored
201
                    if ($free==1 && $is_free==0){
董瑞恩 authored
202
                        $price-=$cost['cost'];
董瑞恩 authored
203
                        Db::name('users')->where('id',$users_id)->update(['is_free'=>1]);
董瑞恩 authored
204
                    }
董瑞恩 authored
205 206
                }
                //昨天预设开始前使用,今天预设结束后停止
董瑞恩 authored
207 208
                if(($new_start_time > $YesterdayEndTime && $new_start_time < $YesterdayStateTime) && ($new_end_time > $endTime && $new_end_time < $stateTime)){
                    //存在首小时免费
董瑞恩 authored
209
                    echo 1;
董瑞恩 authored
210 211 212
                    $price+= ceil(($YesterdayStateTime-$new_start_time)/3600) *  $cost['cost']
                            +ceil(($endTime-$YesterdayStateTime)/3600) *  $interval['price']
                            +ceil(($new_end_time-$endTime)/3600) * $cost['cost'];
董瑞恩 authored
213
                    if ($free==1 && $is_free==0){
董瑞恩 authored
214
                        $price-=$cost['cost'];
董瑞恩 authored
215
                        Db::name('users')->where('id',$users_id)->update(['is_free'=>1]);
董瑞恩 authored
216
                    }
董瑞恩 authored
217
                }
董瑞恩 authored
218
                //昨天预设开始后使用,今天预设结束前停止
董瑞恩 authored
219
                if(($new_start_time > $YesterdayStateTime && $new_start_time < strtotime('00:00:00')) && ($new_end_time > strtotime('00:00:00') && $new_end_time < $endTime)){
董瑞恩 authored
220
                    echo 1;
董瑞恩 authored
221 222
                    $price+= ceil(($new_end_time-$new_start_time)/3600) *  $interval['price'];
                }
董瑞恩 authored
223
                //昨天预设开始后使用,今天预设结束后停止
董瑞恩 authored
224
                if(($new_start_time > $YesterdayStateTime && $new_start_time < strtotime('00:00:00')) && ($new_end_time > $endTime && $new_end_time < $stateTime)){
董瑞恩 authored
225
                    echo 1;
董瑞恩 authored
226 227 228
                    $price+= ceil(($endTime-$new_start_time)/3600) *  $interval['price']
                            +ceil(($new_end_time-$endTime)/3600) * $cost['cost'];
                }
董瑞恩 authored
229
                //昨天预设开始后使用,今天预设开始前停止
董瑞恩 authored
230
                if(($new_start_time > $YesterdayStateTime && $new_start_time < strtotime('00:00:00')) && ($new_end_time > $stateTime && $new_end_time < ($new_start_time+86400))){
董瑞恩 authored
231
                    echo 1;
董瑞恩 authored
232 233 234 235
                    $price+= ceil(($endTime-$new_start_time)/3600) *  $interval['price']
                            +ceil(($stateTime-$endTime)/3600) * $cost['cost']
                            +ceil(($new_end_time-$stateTime)/3600) * $interval['price'];
                }
董瑞恩 authored
236
            }
董瑞恩 authored
237
        }
董瑞恩 authored
238 239 240 241 242
        if ($price > $cost['ceiling']){
            $price = $cost['ceiling'];
        }
        $numPrice = $dayPrice+$price;
        return $numPrice;
董瑞恩 authored
243 244
    }
董瑞恩 authored
245 246 247 248 249 250 251 252 253 254 255 256 257
    //获取整天的价格
    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']);
        }
董瑞恩 authored
258 259 260 261

        if ($price > $cost['ceiling']){
            $price = $cost['ceiling'];
        }
董瑞恩 authored
262 263
        return $price;
    }
董瑞恩 authored
264 265

董瑞恩 authored
266 267 268 269 270 271 272 273 274
    /**
     * @title 统一下单
     * @description 微信统一下单
     * @author 董瑞恩
     * @url /portal/order/pay
     * @method GET
     *
     * @param name:order_no type:String require:1 default:无 other: desc:订单号
     *
董瑞恩 authored
275
     * @return data:返回用于调用支付的参数
董瑞恩 authored
276 277 278
     */
    public function pay($order_no){
        $order=Db::name('order')->where(['order_no'=>$order_no,'state'=>2])->find();
董瑞恩 authored
279
        $openId=Db::name('users')->where('id',$order['users_id'])->find()['open_id'];
董瑞恩 authored
280
        $body='支付';
董瑞恩 authored
281
        $price=$order['price']*1;//订单价格
董瑞恩 authored
282
        $notify_url=url('order/notify','','',true);//回调地址
董瑞恩 authored
283
        $out_trade_no=$order_no.$this->create_noncestr(4);
董瑞恩 authored
284
        $wxPay=new WeixinPay($openId,$out_trade_no,$body,$price,$notify_url);
董瑞恩 authored
285 286 287 288 289 290 291 292 293 294 295 296 297 298
        $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);
董瑞恩 authored
299
        }
董瑞恩 authored
300
董瑞恩 authored
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316
    }

    //支付回调接口
    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);
董瑞恩 authored
317
        $order_no =substr($data['out_trade_no'], 0, -4);
董瑞恩 authored
318 319 320 321 322 323 324 325 326 327 328 329 330 331
        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>";

        }
    }
董瑞恩 authored
332 333 334 335 336 337 338 339 340
    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;
    }
董瑞恩 authored
341
}