使用redis bitmap 在微擎内做公众号的签到活动

33 篇文章 0 订阅
21 篇文章 0 订阅

先说下业务规则 首次签到可获得奖励   以及连续2天签到可获得奖励

因为使用的是openid 而非用户的uid

 因此 此处的设计的key 为 openid  而判断用户是否签到 的偏移量 为以某个起始时间 未开始的便宜来那个计算

另外还有一种方案是  以当天的日期为key  而偏移量 则为用户的 uid (此处不采用的原因为 我们的业务uid 总量不算大 但是 间隔比较大 可能造成很大的  0 间隔)

 

redis  事件记录 RedisManager
    获取 单例 getRedisConn
    签到 setSignUser($openid)
    判断今天签到 getTodaySign($openid)
    判断某天签到 getThisDaySign($openid,$date)
    计算总的签到数 countAllSignDay($openid)
    计算连续签到数 countContinueSignDay($openid)
    计算还差几次签到可抽奖 getAwardNeedDays($openid)
    鉴定今天是否能抽奖 decide_award($openid)
 


class RedisManager
{
    private static $redisInstance;

    const SIGNSTARTDATA="2019-01-03";
    const CANAWARD=2002;
    const NOTAWARD=2004;
    const SIGNDAYSCANAWARD=2006;
    const SIGNDAYSCANNOTAWARD=2007;
    const FISRTSIGN=2008;
    const REPEATSIGN=2009;
    const SUFFIX="_2019";
    const PREFIX="sign_";

    private function __construct(){}

     static public function getRedisConn(){
        if(!self::$redisInstance instanceof self){
            self::$redisInstance = new self;
        }
        $temp = self::$redisInstance;
        return $temp->connRedis();
    }

    static  function connRedis()
    {
      
        try {
            $redis_ocean = new Redis();
            $redis_ocean->connect("127.0.0.1","6333");
            $redis_ocean->auth("Zdklingchen");

        }catch (Exception $e){
            echo $e->getMessage().'<br/>';
        }

        return $redis_ocean;
    }

    static function setSignUser($openid){//签到
        $redis=RedisManager::getRedisConn();
        $cacheKey=RedisManager::PREFIX.$openid.RedisManager::SUFFIX;
        $startDate = RedisManager::SIGNSTARTDATA;
        $todayDate = date("Y-m-d");       
        $startTime = strtotime($startDate);
        $todayTime = strtotime($todayDate);
        $offset = floor(($todayTime - $startTime) / 86400);
       return  $redis->setBit($cacheKey, $offset, 1);
    }


     static function getTodaySign($openid){//判断某个openid 今天
        $redis=RedisManager::getRedisConn();
        $cacheKey=RedisManager::PREFIX.$openid.RedisManager::SUFFIX;
        $startDate = RedisManager::SIGNSTARTDATA;
        $todayDate = date("Y-m-d");       
        $startTime = strtotime($startDate);
        $todayTime = strtotime($todayDate);
        $offset = floor(($todayTime - $startTime) / 86400);
        $bitStatus = $redis->getBit($cacheKey, $offset);
        return $bitStatus;
    }

    static function getThisDaySign($openid,$date){//判断某个openid 是否在某天签到 0/1
        $redis=RedisManager::getRedisConn();
       $cacheKey=RedisManager::PREFIX.$openid.RedisManager::SUFFIX;
        $startDate = RedisManager::SIGNSTARTDATA;
        $todayDate = $date;       
        $startTime = strtotime($startDate);
        $todayTime = strtotime($todayDate);
        $offset = floor(($todayTime - $startTime) / 86400);
      

        $bitStatus = $redis->getBit($cacheKey, $offset);
        return $bitStatus;
    }

    static  function countAllSignDay($openid){//计算累计签到次数
        $redis=RedisManager::getRedisConn();
        $cacheKey=RedisManager::PREFIX.$openid.RedisManager::SUFFIX;
       return  $redis->bitCount($cacheKey);
    }


    static  function countContinueSignDay($openid){//计算连续签到次数

        $redis=RedisManager::getRedisConn();
        $cacheKey=RedisManager::PREFIX.$openid.RedisManager::SUFFIX;      
        
        $todayIsSign=RedisManager::getTodaySign($openid);
        if ($todayIsSign == 0) {
          $todayDate=date("Y-m-d",strtotime("-1 day"));       
        }else{
          $todayDate = date("Y-m-d"); 
        }
        $startDate = RedisManager::SIGNSTARTDATA;
        $startTime = strtotime($startDate);  
        $todayTime = strtotime($todayDate);
    
        $offset = floor(($todayTime - $startTime) / 86400);
   
        $countContinueSignDayNum=0;
        for ($i=$offset; $i >= 0; $i--) { 
            
            $BitRes=$redis->getBit($cacheKey, $i);
            if ($BitRes == 1) {
                $countContinueSignDayNum++;
                continue;
            }else{
                break;
            }
           
        }
        return $countContinueSignDayNum;

    }

    static function getAwardNeedDays($openid){
        $todayIsSign=RedisManager::getTodaySign($openid);
        $totalCountSign=RedisManager::countAllSignDay($openid);

         if ($totalCountSign == 1 && $todayIsSign == 1) {//今天还没签到
             $data=array(
                     "code"=>RedisManager::FISRTSIGN,
                     "needsDays"=>2,
                     "msg"=> "First sign has sign,can get arawd",
                 );
             return $data;
         }

        if ($totalCountSign == 0 && $todayIsSign == 0) {//今天还没签到
             $data=array(
                     "code"=>RedisManager::FISRTSIGN,
                     "needsDays"=>0,
                     "msg"=> "First sign has  not sign",
                 );
             return $data;

        }else{
             $YesterDay=date("Y-m-d",strtotime("-1 day"));
            $YesterDaySignData=RedisManager::getThisDaySign($openid,$YesterDay);
            if ($YesterDaySignData == 0) {//昨日没签到
                   if ($todayIsSign == 0) {
                         $data=array(
                             "code"=>RedisManager::SIGNDAYSCANAWARD,
                             "needsDays"=>2,
                            "msg"=> "Today is  not sign And YesterDay is not sign ",
                             );
                        return $data;
                   }else{
                        $data=array(
                             "code"=>RedisManager::SIGNDAYSCANAWARD,
                             "needsDays"=>1,
                            "msg"=> "Today  has  sign But YesterDay is not sign  ",
                             );
                        return $data;
                   }
            }else{
               $continueSignNum=RedisManager::countContinueSignDay($openid);

                if ($totalCountSign == $continueSignNum && $totalCountSign > 0 ) {//签到一直没间断
                        if ($todayIsSign == 0) {
                                if ($totalCountSign%2 == 0 ) {
                                         $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                            "needsDays"=>1,
                                            "msg"=> "Today is  not sign  But sign is continue  ",
                                        );
                                        return $data;

                                }else{

                                     $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                             "needsDays"=>2,
                                            "msg"=> "Today is  not sign  But sign is continue   ",
                                             );
                                 return $data;

                                }

                        }else{//今天签到了

                                  if ($totalCountSign%2 == 0 ) {
                                         $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                            "needsDays"=>1,
                                            "msg"=> "Today has sign And sign is continue  ",
                                        );
                                        return $data;

                                }else{

                                     $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                             "needsDays"=>2,
                                            "msg"=> "Today has sign And sign is continue  ",
                                             );
                                 return $data;

                                }

                        }

                }else{

                      if ($todayIsSign == 0) {
                            if ($continueSignNum%2 == 0 ) {

                                 $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                             "needsDays"=>1,
                                            "msg"=> "Today is  not sign But sign is not  continue  ",
                                             );
                                 return $data;

                            }else{

                                $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                             "needsDays"=>2,
                                            "msg"=> "Today is  not sign  But sign is not  continue   ",
                                             );
                                 return $data;

                            }
                      }else{
                         if ($continueSignNum%2 == 0 ) {

                                 $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                             "needsDays"=>2,
                                            "msg"=> "Today is  has  sign  But sign is not  continue   ",
                                             );
                                 return $data;

                            }else{

                                $data=array(
                                            "code"=>RedisManager::SIGNDAYSCANAWARD,
                                             "needsDays"=>1,
                                            "msg"=> "Today is  has  sign  But sign is not  continue   ",
                                             );
                                 return $data;

                            }

                      }


                }


            }

        }

    }

    static function decide_award($openid){ //返回一个数组 2004 不抽奖 2002抽奖
        
        $todayIsSign=RedisManager::getTodaySign($openid);
        $totalCountSign=RedisManager::countAllSignDay($openid);
        if ($todayIsSign == 0) {//今天没签到
             $data=array(
                     "code"=>RedisManager::NOTAWARD,
                     "msg"=>"今日还没签到",
                 );
            return $data;

        }
        if ($todayIsSign == 1 && $totalCountSign == 1) {//首次签到 今天签到 +总签到数=1
            $data=array(
                "code"=>RedisManager::CANAWARD,
                "msg"=>"首次签到",
            );
            return $data;
        }else{
            $YesterDay=date("Y-m-d",strtotime("-1 day"));
            $YesterDaySignData=RedisManager::getThisDaySign($openid,$YesterDay);
            if ($YesterDaySignData == 0) {  //昨天没签到
                $data=array(
                     "code"=>RedisManager::NOTAWARD,
                     "msg"=>"签到成功,但是您昨天没签到,明天继续签到可获得奖励",
                 );
                 return $data;
            }else{//因为今天已经签到 所以 连续签到从今天算 最小为1
               $continueSignNum=RedisManager::countContinueSignDay($openid);
                if ($totalCountSign == 2 &&  $continueSignNum == 2 ) {//总签到 跟连续签到 都为2 则说明昨天是首次签到
                     $data=array(
                            "code"=>RedisManager::NOTAWARD,
                            "msg"=>"签到成功,明天继续签到可获得奖励",
                        );
                         return $data;
                }else{//昨天签到不是首次签到 
                    if ($totalCountSign == $continueSignNum && $totalCountSign > 0 ) {//首次签到一直没断
                        if ($totalCountSign%2 == 0 ) {
                            //偶数次不发
                              $data=array(
                                    "code"=>RedisManager::NOTAWARD,
                                    "msg"=>"签到成功,明天继续签到可获得奖励",
                                 );
                         return $data;
                        }else{
                             $data=array(
                                    "code"=>RedisManager::CANAWARD,
                                        "msg"=>"签到成功,今天可抽奖",
                               );
                              return $data;
                        }
                    }else{
                        if ($continueSignNum%2 == 0 ) {
                            //偶数次发
                           $data=array(
                                    "code"=>RedisManager::CANAWARD,
                                        "msg"=>"签到成功,今天可抽奖",
                               );
                              
                            return $data;
                        }else{
                             $data=array(
                                    "code"=>RedisManager::NOTAWARD,
                                    "msg"=>"签到成功,明天继续签到可获得奖励",
                                 );
                              return $data;
                        }
                    }
                }

        
            }
        }

    }
    

    private function __clone(){}
    

}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值