先說下業務規則 首次簽到可獲得獎勵 以及連續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(){}
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結