objMemcached = new Memcached(); $this->objRank = new Rank(); $this->uid = $uid; $this->eventsId = $eventsId; $this->objDLotteryEvents = new LotteryEvents(); $this->objDLotteryPrize = new LotteryPrize(); $this->objDLotteryPrizeVirtualData = new LotteryPrizeVirtualData(); $this->objDLotteryData = new LotteryData(); $this->objMlottery = new Lottery(); $this->objMLotteryEventsLimitations = new LotteryEventsLimitations(); $this->objMLotteryLog = new LotteryLog($uid,$eventsId); $this->version = '0.1'; $this->thisTime = time(); } public function verifyPrize(){ $eventsAndPrize = $this->objMlottery->getOneLotteryEventsAndPrize($this->eventsId); # 活动是否开始 if($this->thisTime < $eventsAndPrize['events']['begin_time'] || $this->thisTime > $eventsAndPrize['events']['end_time']){ return false; } # 活动限制 if(!$this->objMLotteryEventsLimitations->ckEventRestrictions($this->uid,Request::ip(), $this->eventsId)){ return false; } # 排列顺序 $newPrize = array(); foreach($eventsAndPrize['prize'] as $prize){ $prize_id = $prize['id']; $begin_hour = $prize['begin_hour']; $end_hour = $prize['end_hour']; $this_hour = date("H",$this->thisTime); # 获奖是否在此抽奖时间段 if(!($this_hour >=$begin_hour && $this_hour<$end_hour)){ continue; } # 验证当前奖项是否显示 if($prize['display']==LotteryPrize::PRIZE_DISPLAY_HIDE){ continue; } # 验证当前将奖项 库存数量 if($prize['prize_num']-$prize['prize_winning_num'] <= 0){ continue; } # 验证是否在 黑 & 白 名单中 if($this->ckBlackAndWhiteList($prize_id) == false){ continue; } # 获取下一次的中奖时间 【开始抽奖逻辑】 $nextWinTime = $this->getNextWinTime($prize_id); $newPrize[$nextWinTime] = $prize_id; } # 中奖顺序 ksort($newPrize,SORT_NUMERIC); foreach($newPrize as $key => $this_prize_id){ $newPrize[$key] = $eventsAndPrize['prize'][$this_prize_id]; } foreach($newPrize as $prize){ $prize_id = $prize['id']; $begin_hour = $prize['begin_hour']; $end_hour = $prize['end_hour']; $this_hour = date("H",$this->thisTime); # 获奖是否在此抽奖时间段 if(!($this_hour >=$begin_hour && $this_hour<$end_hour)){ continue; } # 验证当前奖项是否显示 if($prize['display']==LotteryPrize::PRIZE_DISPLAY_HIDE){ continue; } # 验证当前将奖项 库存数量 if($prize['prize_num']-$prize['prize_winning_num'] <= 0){ continue; } # 验证是否在 黑 & 白 名单中 if($this->ckBlackAndWhiteList($prize_id) == false){ continue; } # 获取下一次的中奖时间 【开始抽奖逻辑】 $nextWinTime = $this->getNextWinTime($prize_id); if (!$this->lock($prize_id)) return false; if (!$nextWinTime) { $isWin = false; $this->setNextWinTime($prize_id); } elseif ($nextWinTime <= $this->thisTime) { $isWin = true; # 发奖 $lotteryDataId = $this->awards($prize_id,$nextWinTime); $this->setNextWinTime($prize_id); $this->unlock($prize_id); return $lotteryDataId; break; } # 检查是否百分之百中奖用户名单中 if($this->ckHundredPercentList($prize_id)){ $isWin = true; # 发奖 $lotteryDataId = $this->awards($prize_id,$this->thisTime); $this->setNextWinTime($prize_id); $this->unlock($prize_id); return $lotteryDataId; break; } $this->unlock($prize_id); continue; } return false; } /** * 清除下次中奖时间 并且动态计算下次中奖时间 */ public function clear_draw_next_time($prize_id) { $memkey = $this->getCacheKeyOfTimeBucketWinTimes($prize_id); $this->objMemcached->delete($memkey); $memkey = $this->getCacheKeyOfNextWinTime($prize_id); $this->objMemcached->delete($memkey); $this->setNextWinTime($prize_id); } /** * 检查是否是百分百中奖名单中的用户 */ public function ckHundredPercentList($prize_id){ // 查看百分百中奖名单中的用户 $hundred_percent_list = $this->objMemcached -> get('lottery_prize_'.$prize_id.'_hundred_percent_list'); if(!empty($hundred_percent_list)){ if(isset($hundred_percent_list[$this->uid])){ return true; } } return false; } /** * 检查白名单 & 黑名单 */ public function ckBlackAndWhiteList($prize_id){ // 查看黑名单 $black_list = $this->objMemcached -> get('lottery_prize_'.$prize_id.'_black_list'); if(!empty($black_list)){ if(isset($black_list[$this->uid])){ return false; } } // 查看白名单 $white_list = $this->objMemcached -> get('lottery_prize_'.$prize_id.'_white_list'); if(!empty($white_list)){ if(!isset($white_list[$this->uid])){ return false; } } return true; } /** * 发奖逻辑 */ public function awards($prize_id,$winTime){ $eventsAndPrize = $this->objMlottery->getOneLotteryEventsAndPrize($this->eventsId); $info = array( 'events_id' => $this->eventsId, 'prize_id' => $prize_id, 'uid' => $this->uid, 'winners_time' => $winTime, 'winning_time' => $this->thisTime, 'run_time_data' => $eventsAndPrize, ); $prize = $eventsAndPrize['prize'][$prize_id]; if($prize['type'] == LotteryPrize::TYPE_ENTITY){ $virtual_condition = "prize_id = {$prize_id} AND lottery_data_id = 0 " ; $LotteryPrizeVirtualDataID = $this->objDLotteryPrizeVirtualData->findIdsBy ( $virtual_condition, '0,1' ,'id desc'); $LotteryPrizeVirtualDataID = array_pop($LotteryPrizeVirtualDataID); $prizeVirtualData = $this->objDLotteryPrizeVirtualData->get($LotteryPrizeVirtualDataID); $info['virtual_data'] = $prizeVirtualData['data']; $info['create_time'] = $this->thisTime; } $lotteryDataId = $this->objDLotteryData -> add($info); # 判断是否是 虚拟类 if($prize['type'] == LotteryPrize::TYPE_ENTITY){ $virtualInfo = array( 'uid' => $this->uid, 'lottery_data_id' => $lotteryDataId, 'events_id' => $this->eventsId, ); $this->objDLotteryPrizeVirtualData->modify($virtualInfo,array('id' => $LotteryPrizeVirtualDataID)); } $this->objDLotteryPrize -> upPrizeWinningNum($prize_id, 1); # 用户记录 $this->objMLotteryEventsLimitations->setUserWinningNum($this->uid, $this->eventsId); # 记录一条获奖日志 $other = $info; $this->objMLotteryLog ->addLog(DLog::LOG_TYPE_RECEIVE, $other); return $lotteryDataId; } /** * 开启抽奖锁 * @return boolean | null */ public function lock($prize_id) { return $this->objMemcached->add($this->getCacheKeyOfLock($prize_id), true, 10); } /** * 关闭抽奖锁 * @return boolean | null */ public function unlock($prize_id) { return $this->objMemcached->delete($this->getCacheKeyOfLock($prize_id)); } /** * 获取抽奖锁 cache key * @return string */ public function getCacheKeyOfLock($prize_id) { return "lottery_draw_lock_{$prize_id}"; } /** * 设置当天下次中奖时间 * @return boolean | null */ public function setNextWinTime($prize_id) { $hasWinTotal = $this->objDLotteryData->getTodayHasWinTotal($prize_id); $timeBucketWinTimes = $this->getTimeBucketWinTimes($prize_id); $next_win_time = $this->objRank->winnerCal($timeBucketWinTimes, $hasWinTotal); return $this->objMemcached->set($this->getCacheKeyOfNextWinTime($prize_id), $next_win_time, 60*60*24); } /** * 获取当天每个时间断中奖次数 * @return array */ public function getTimeBucketWinTimes($prize_id) { $memkey = $this->getCacheKeyOfTimeBucketWinTimes($prize_id); $timeBucketWinTimes = $this->objMemcached->get($memkey); if (!$timeBucketWinTimes) { $replyInfo = $this->objDLotteryPrize->get ( $prize_id ); // 获取当前奖项详情 $eventsData = $this->objDLotteryEvents->get($this->eventsId); $gift_amount = $replyInfo['prize_num']; if ($gift_amount <= 0) { return false; } $start_time = $eventsData['start_time']; $end_time = $eventsData['end_time']; $today_time = mktime(0,0,0); $overTotal = ceil(($end_time - $today_time) / (60*60*24));//剩余天数 $hasWinTimes = $replyInfo['prize_winning_num']; $todayHasWinTimes = $this->objDLotteryData->getTodayHasWinTotal($prize_id); $needWinTimes = ceil(($gift_amount - $hasWinTimes) / $overTotal) - $todayHasWinTimes; $timeBucketWinTimes = $this->objRank->getTimeValue($needWinTimes, date('G'), $replyInfo['end_hour']-1); $this->objMemcached->set($memkey, $timeBucketWinTimes, 60 * 60 * 24); } return $timeBucketWinTimes; } /** * 获取当天中奖数 */ public function getCacheKeyOfTimeBucketWinTimes($prize_id){ return date('Y_m_d',$this->thisTime).'_'.$prize_id.'_winning_num'; } /** * 获取下次中奖时间 * @return string */ public function getNextWinTime($prize_id) { $next_win_time = $this->objMemcached->get($this->getCacheKeyOfNextWinTime($prize_id)); return $next_win_time; } /** * cache中下次中奖时间的key */ public function getCacheKeyOfNextWinTime($prize_id){ return date('Y_m_d',$this->thisTime).'_'.$prize_id.'_next_time'; } }