php用户签到,领取红包

  1 <?php
  2 /**
  3  * create by jxkshu
  4  * Date 2017-09-28
  5  * 用户签到领取红包
  6  */
  7 /**
  8 Redis     
  9     set: key  signed:user:mark  标记已签到用户
 10          val  user_id
 11 
 12     zset key    signed:user:today:share:num     记录当天用户分享的次数,凌晨4点删除  
 13          score  分享的次数
 14          val    用户ID
 15     zset key    signed:user:today:replenishment:num  记录当天用户已经补签的次数,凌晨4点删除  
 16          score  当天补签的次数
 17          val    用户ID    
 18 */
 19 header("content-type:text/html;charset=utf-8");
 20 require_once('api.base.php');
 21  
 22 class m_signed extends base
 23 {
 24     private $redis = null;
 25     private $log_dir = null;
 26 
 27     public function __construct(){
 28         parent::__construct();
 29 
 30         $this->init();
 31         // parent::signer($_POST);
 32         // parent::tokengoon($_POST);
 33        
 34         // 连接redis 
 35         $this->redis = new MyRedis;
 36         $this->redis = $this->redis->getRedisCli();
 37 
 38         // 创建单个文件夹
 39         $this->log_dir = __DIR__ . '/../log/return_red_envelope/signed/';
 40         if(!is_dir($this->log_dir)):
 41             mkdir($this->log_dir);
 42             chmod($this->log_dir, 0777);
 43         endif;
 44     }
 45 
 46 
 47     /**
 48      * 用户 签到或者补签
 49      * @param  array $post 客户端传递的数据
 50      * @return array 抢红包后的数据     
 51      */
 52     public function signed($post){
 53 
 54         parent::signer($_POST);
 55         parent::tokengoon($_POST);
 56         $user_id = (int)trim($post['user_id']);
 57 
 58         // 延迟0.2秒,防并发
 59         usleep(200000);
 60         // 判断用户是签到还是补签
 61         if( empty($post['type']) || $post['type']==0):
 62             // 判断用户是否已签
 63             $key = 'signed:user:mark';
 64             if(($this->redis->sIsMember($key, $user_id))):
 65                 return ['status'=>'fail', 'msg'=>'已签到']; 
 66             else:
 67                 // 二次判断用户是否已经签到
 68                 $day_start = strtotime(date('Y-m-d 0:0:0',time()));
 69                 $day_end = strtotime(date('Y-m-d 0:0:0',time()))+86399;
 70                 $sql = "SELECT count(id) as total from sign_red_envelopes where uid=$user_id and time>=$day_start and time<=$day_end and amount>0";
 71                 $sign_num = (int) parent::result_first($sql);
 72                 if($sign_num>0):
 73                     return ['status'=>'fail', 'msg'=>'已签到']; 
 74                 endif;
 75             endif;
 76             // 用户签到
 77             $res = $this->userSigned($user_id, $post['time']);
 78         else:
 79             if( $post['time'] >= strtotime(date('Y-m-d 0:0:0'))):
 80                 return ['status'=>'fail', 'msg'=>'日期错误']; 
 81             endif;
 82             $res = $this->userReplenishment($user_id, $post['time']);
 83         endif;
 84 
 85         if($res['status']=='fail'):
 86             $this->writeLog(__FILE__, __LINE__, $res['msg']);
 87         endif;
 88        return $res;
 89     }
 90 
 91 
 92     /**
 93      *  用户补签
 94      * @param  int $user_id   用户ID
 95      * @param  int $time      用户签到时间
 96      * @return array  status:状态、msg:信息、amount:奖励金额、replenishment_num:剩余可以补签的次数
 97      */
 98     protected function userReplenishment($user_id, $time){
 99  
100         // 获取用户当天已经补签的次数
101         $replenishment = $this->redis->zScore('signed:user:today:replenishment:num', $user_id);
102         // 获取用户当天线下消费额度
103         $tim = date('Ymd');
104         $sql = "SELECT sum(amount) as total_amount FROM payinfo where pay_dateint='$tim' and uid=$user_id and status=1 and is_ol_verify=0";
105         $total_amount = (int) parent::result_first($sql);
106 
107         // 判断用户补签次数是否超出
108         $total_amount  = (int) ($total_amount/58);
109         $replenishment = (int)$replenishment;
110         if( $total_amount<=$replenishment ):
111             return ['status'=>'fail', 'msg'=>'补签失败,消费额度不足!'];
112         endif;
113       
114         // 补签次数累加1
115         $res = $this->redis->zIncrBy('signed:user:today:replenishment:num', 1, $user_id);
116         if(empty($res)):
117             return ['status'=>'fail', 'msg'=>'补签次数累加失败!'];
118         endif;
119        
120         //获取用户补签奖励金额
121         $amount = mt_rand(50, 100) / 100;
122 
123         // 记录用户补签信息
124         $data = [
125             'uid'  => $user_id,
126             'type' => 1,
127             'amount' => $amount,
128             'time' => $time,
129         ];
130         $res = parent::insert('sign_red_envelopes', $data);
131         if(empty($res)):
132             return ['status'=>'fail', 'msg'=>'写入补签红包记录数据库失败!'];
133         endif;
134 
135         // 累加用户签到奖励
136         $sql = "UPDATE userinfo SET sign_reward=(sign_reward+$amount),total_sign_reward=(total_sign_reward+$amount) where id=$user_id limit 1";
137         $res = parent::query($sql);
138         if(empty($res)):
139             return ['status'=>'fail', 'msg'=>'累加用户补签奖励失败!'];
140         endif;
141         return ['status'=>'success', 'msg'=>'用户补签成功',  'amount'=>$amount, 'replenishment_num'=>($total_amount-$replenishment)];
142     }
143 
144 
145 
146     /**
147      *  用户签到
148      * @param  int $user_id   用户ID
149      * @param  int $time      用户签到时间
150      * @return array 
151      */
152     protected function userSigned($user_id, $time){
153  
154         // 获取签到奖励金额
155         $amount = self::getSignedAmount($user_id);
156         $data = [
157             'uid' => $user_id,
158             'amount' => $amount,
159             'time' => $time,
160         ];
161         $res = parent::insert('sign_red_envelopes', $data);
162         if(empty($res)):
163             return ['status'=>'fail', 'msg'=>'写入签到红包记录数据库失败!'];
164         endif;
165 
166         // 累加用户签到奖励
167         $sql = "UPDATE userinfo SET sign_reward=(sign_reward+$amount),total_sign_reward=(total_sign_reward+$amount) where id=$user_id limit 1";
168         $res = parent::query($sql);
169         if(empty($res)):
170             return ['status'=>'fail', 'msg'=>'累加用户签到奖励失败!'];
171         endif;
172 
173         // 标记用户已经签到
174         $res = $this->redis->sAdd('signed:user:mark', $user_id);
175         return ['status'=>'success', 'amount'=>$amount];
176     }
177 
178 
179     /**
180      * 获取用户签到奖励金额
181      * @param  int      $user_id
182      * @return float    奖励金额
183      */
184     protected static function getSignedAmount($user_id){
185 
186         // 判断用户是不是第一次签到
187         $sql = "SELECT count(id) as total FROM sign_red_envelopes where uid=$user_id limit 1";
188         $total = parent::result_first($sql);
189 
190         // 获取签到奖励金额
191         if(empty($total)):
192             // 首次签到
193             $amount = mt_rand(1,2);
194         else:
195             //提升红包额度
196             $sql = "SELECT share_num from userinfo where id=$user_id limit 1";
197             $share_num = parent::result_first($sql);
198             $share_num = ($share_num>20 ? 20 : $share_num);
199             $min = (0.1 + (0.1 * ($share_num*0.1))) * 100; 
200             $max = (1 + (1*($share_num*0.05))) * 100; 
201             $max = ($max>200 ? 200 : $max);
202 
203             $amount = mt_rand($min, $max) / 100;
204             $amount = number_format($amount, 2);
205         endif;
206 
207         return $amount; 
208     }
209  
210 
211  // -------------------------------- 用户将奖励提转到58券
212  
213 
214     /**
215      * 用户将奖励提转到58券
216      * @param  array $post=>user_id  用户id
217      * @return array       
218      */
219     public function rewardTo58voucher($post){
220 
221         parent::signer($_POST);
222         parent::tokengoon($_POST);
223         // 获取用户已经累计的签到红包
224         $sql = 'SELECT id,sign_reward FROM userinfo WHERE id='.$post['user_id'].'  limit 1';
225         $userinfo = parent::fetch_first($sql);
226         if($userinfo['sign_reward']<20):
227             return ['errcode'=>'44','msg'=>'代金券未满20'];
228         endif;
229 
230         // 红包转换成58券
231         $sql='UPDATE userinfo SET sign_reward=0, red_reward=(red_reward+'.$userinfo['sign_reward'].')  WHERE id='.$post['user_id'].'  LIMIT 1';
232         $res = parent::query($sql);
233         if(empty($res)):
234             return ['errcode'=>'3','msg'=>'服务器异常!'];
235         endif;
236         // 记录行为到红包
237         $tim = time();
238         $data = [
239             'uid'=>$post['user_id'],
240             'orderid'=>'',
241             'amount'=>$userinfo['sign_reward'],
242             'packet_status'=>1,
243             'receive_time'=>date('Y-m-d H:i:s', $tim),
244             'packet_type'=>6,
245             'add_time'=>date('Y-m-d H:i:s', $tim),
246             'dateint'=>date('Ymd', $tim),
247         ];
248         $res = parent::insert('redpacket', $data);
249         if(empty($res)):
250             return ['errcode'=>'400','msg'=>'提转成功!但记录提转信息失败!'];
251         endif;
252         return ['errcode'=>0,'msg'=>'提转成功!'];
253     }
254 
255 
256     /**
257      * 获取剩余补签次数
258      * @param  int $user_id 用户ID
259      * @return array          
260      */
261     public function getSignCard($user_id){
262         
263         parent::signer($_POST);
264         parent::tokengoon($_POST);
265         // 获取用户当天已经补签的次数
266         $replenishment = $this->redis->zScore('signed:user:today:replenishment:num', $user_id);
267         // 获取用户当天线下消费额度
268         $tim = date('Ymd');
269         //$sql = "SELECT sum(amount) as total_amount FROM payinfo where pay_dateint='$tim' and uid=$user_id and status=1 and (order_type=0 or order_type=4)";
270         $sql = "SELECT sum(amount) as total_amount FROM payinfo where pay_dateint='$tim' and uid=$user_id and status=1 ";
271 
272         $total_amount = (int) parent::result_first($sql);
273        
274         // 判断用户补签次数是否超出
275         $total_amount  = (int) ($total_amount/58);
276         $replenishment = (int) $replenishment;
277 
278         return ['card_num'=>($total_amount - $replenishment)];
279     }
280 
281 
282     // 用户分享朋友圈来提升签到红包额度
283     public function userShareAppToPeople($user_id){
284    
285         parent::signer($_POST);
286         // 将分享次数暂时记录到redis,每天凌晨定时任务在写入数据库
287         $key = 'signed:user:today:share:num';
288         $res = $this->redis->zIncrBy($key, 1, $user_id);
289         return ['signed_num'=>$res];
290     }
291 
292  
293     // 写日志
294     private function writeLog($fil, $row, $remarks=''){
295         $file = $this->log_dir . 'signed-'.date('Y-m').'.txt';
296         $content = $fil.'  Line ' . $row . ' failed '.date('Y-m-d H:i:s')."  $remarks 

";
297         file_put_contents($file, $content, FILE_APPEND);
298     }
299  
300 
301 
302 
303     //----------------------------  获取用户签到界面的信息
304     
305     public function getSignPageInfo($post){
306        
307         parent::signer($_POST);
308         parent::tokengoon($_POST);
309         $user_id = parent::parseuid($post);
310         $data = [];
311 
312         // 分享URL
313         $tim = time();
314         $salt = '58_life_circle_sign_share';
315         $sign = mb_strcut(md5('58_life_circle_sign_share'.$tim), 0, 6, 'utf8');
316         $data['share_url'] = 'http://api.licheepay.com/lzf/html/sign_share/h5.html?uid='.$user_id.'&time='.$tim.'&sign='.$sign;
317         // 广告图
318         $data['header_advert'] = [
319             // [
320             //     'img'=> 'http://adm.licheepay.com/upload/mall/1509331172.png',
321             //     'url'=> 'app_web_$$$https://s.click.taobao.com/7IlNyYw$$$',
322             // ],
323             // [
324             //     'img'=> 'http://adm.licheepay.com/upload/mall/1509523936.png',
325             //     'url'=> 'app_web_>>>http://mp.weixin.qq.com/s/BDSD_jDgCmMxfCdieLxtxg<<<',
326             // ],
327             [
328                 'img'=> 'http://adm.licheepay.com/upload/img/ad/20170508161142.png',
329                 'url'=> 'app_web_>>>http://mp.weixin.qq.com/s/BDSD_jDgCmMxfCdieLxtxg<<<',
330             ],
331 
332         ];
333         // 获取累计签到奖励
334         $sql = 'SELECT sign_reward,total_sign_reward FROM userinfo WHERE id='.$user_id.'  limit 1';
335         $temp_user_sign = parent::fetch_first($sql);
336         $data['sign_reward'] = $temp_user_sign['sign_reward'];
337         $data['total_sign_reward'] = $temp_user_sign['total_sign_reward'];
338          
339         // 签到奖励提取状态【是否可提取】
340         $data['extract_status'] = 0;
341         if($temp_user_sign['sign_reward']>=20):
342             $data['extract_status'] = 1;
343         endif;
344 
345 
346         // 签到说明
347         $data['sign_explain'] = '1、签到后可抢代金券红包,满20券可用
348 2、用户每天可签到一次,每次可获得随机劵奖励
349 3、代金券每月15号自动清零,满20券请及时领取
350 4、线下消费满58元,可手动补签1次,当天有效
351 5、签到后分享好友,好友参与可提高次日红包金额';
352 
353         //  签到状态
354         // 判断用户是否已签
355         $data['signed_status'] = 0;
356         $key = 'signed:user:mark';
357         if(($this->redis->sIsMember($key, $user_id))):
358             $data['signed_status'] = 1;
359         endif;
360         // // 二次判断用户是否已经签到 2017-11-01屏蔽
361         $day_start = strtotime(date('Y-m-d 0:0:0',time()));
362         $day_end = strtotime(date('Y-m-d 0:0:0',time()))+86399;
363         $sql = "SELECT count(id) as total from sign_red_envelopes where uid=$user_id and time>=$day_start and time<=$day_end and amount>0";
364         $sign_num = (int) parent::result_first($sql);
365         if($sign_num<1):
366            $data['signed_status'] = 0;
367         else:
368            $data['signed_status'] = 1;
369         endif;
370 
371 
372         //  时间戳
373         $data['time'] = time();
374         return $data;
375     }
376 
377 
378 
379     // 获取用户签到信息日历
380     public function getUserSignInfoCalendar($post){
381        
382         parent::signer($_POST);
383         parent::tokengoon($_POST);
384         $user_id = parent::parseuid($post);
385         
386         // 当前月份
387         $total_day = date('t');
388         $current_month = date('m');
389         $first_day = strtotime(date("Y-m-01"));
390         $last_day  = $first_day + ($total_day*86400) - 1;
391         $sql = "SELECT FROM_UNIXTIME(time,'%e') as day,type 
392                 FROM   sign_red_envelopes 
393                 WHERE  uid=$user_id and time>=$first_day and time<=$last_day";
394         //获取用户签到信息 
395         $sign_info = parent::fetch_all($sql);
396         // 获取用户补签卡
397         $card_num = $this->getSignCard($user_id);
398         $card_num = $card_num['card_num'];
399 
400         $today = date('d'); 
401         // 1:未签、 2:已签到、3:已补签 4:可补签、  5:漏签、 6:不可签、
402         $temp_current = [];
403         for ($i=$total_day; $i>0; $i--) { 
404             $status = 0;
405             // 签到或者补签
406             foreach ($sign_info as $sign) {
407                 if($sign['day']==$i):
408                     $status = empty($sign['type']) ? 2 : 3;
409                     break;
410                 endif;
411             }
412             // 1:未签
413             if($status==0 && $i==$today):
414                 $status = 1;
415             endif;
416             //4:可补签
417             if($status==0 && $i<$today && $card_num>0):
418                 $status = 4;
419                 $card_num--;
420             endif;
421             // 6:不可签
422             if($status==0 && $i>$today):
423                 $status = 6;
424             endif;
425             // 5:漏签
426             if($status==0):
427                 $status = 5;
428             endif;
429             $temp_current[$i] = $status;
430         }
431  
432 
433         // 上月份
434         $last_month = date('m', time()) - 1;
435         if( $last_month<1 ):
436             $last_month = 12;
437             $time_str  = (date('Y',time()) - 1) . '-12-01';
438             $total_day = date('t', strtotime($time_str));
439             $first_day = strtotime($time_str);
440             $last_day  = $first_day + ($total_day*86400) - 1;
441         else:
442             $time_str  =  date('Y',time()) .'-'.$last_month.'-01';
443             $total_day  = date('t', strtotime( $time_str));
444             $last_month = date('m', strtotime( $time_str));
445             $first_day = strtotime( $time_str);
446             $last_day  = $first_day + ($total_day*86400) - 1;
447         endif;
448         $sql = "SELECT FROM_UNIXTIME(time,'%e') as day,type 
449                 FROM   sign_red_envelopes 
450                 WHERE  uid=$user_id and time>=$first_day and time<=$last_day";
451          //获取用户签到信息 
452         $sign_info = parent::fetch_all($sql);
453         // 2:已签到、3:已补签 4:可补签、 5:漏签、  
454         $temp_last = [];
455         for ($i=$total_day; $i>0; $i--) { 
456             $status = 0;
457             // 签到或者补签
458             foreach ($sign_info as $sign) {
459                 if($sign['day']==$i):
460                     $status = empty($sign['type']) ? 2 : 3;
461                 endif;
462             }
463             //可补签
464             if($status==0 && $card_num>0):
465                 $status = 4;
466                 $card_num--;
467             endif;
468             // 5:漏签
469             if($status==0):
470                 $status = 5;
471             endif;
472 
473             $temp_last[$i] = $status;
474         }
475 
476 
477         ksort($temp_current);  //当前月份
478         ksort($temp_last);     //上月份
479         $data = [
480             [
481                 'month'=>$current_month,
482                 'status' =>array_values($temp_current)
483             ],
484             [
485                 'month'  =>$last_month,
486                 'status'=>array_values($temp_last)
487             ],
488         ];
489         return $data;
490     }
491 
492 
493 }//end

下载地址

原文地址:https://www.cnblogs.com/jxkshu/p/8674745.html