zoukankan      html  css  js  c++  java
  • 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

    下载地址

  • 相关阅读:
    Java学习day2
    Java 学习day1
    const
    数组
    scanf、printf、gets、puts的应用及区别
    指针数组和数组指针
    指针函数和函数指针
    nginx Windows版使用说明
    windows平台上nginx部署web.py(转)
    python安装程序是报这样的错UnicodeDecodeError: 'ascii' codec can't decode byte 0xb0 in position 1: ordinal not in range(128)
  • 原文地址:https://www.cnblogs.com/jxkshu/p/8674745.html
Copyright © 2011-2022 走看看