| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 | <?phpnamespace Cas\Module;use KIF\Core\Request;use KIF\Page\Page;use KIF\Verify;use Cas\Dao\LotteryEvents;use KIF\Core\Config;use KIF\Image;use Cas\Dao\LotteryPrize;use KIF\Cache\Memcached;use KIF\Dao\SqlHelper;use Cas\Dao\LotteryPrizeVirtualData;use Cas\Dao\LotteryData;use Cas\Module\LotteryLog;use Cas\Dao\LotteryEventsLog as DLog;/** * * * 抽奖 模型 * * @author lihuanchun */class LotteryDraw  {		private $objMemcached;		private $objRank;		private $uid;		private $eventsId;		private $objDLotteryEvents;		private $objMlottery;		private $objDLotteryPrizeVirtualData;		private $objMLotteryEventsLimitations;		private $objDLotteryData;		private $objMLotteryLog;		private $version;		private $thisTime;		public function __construct($uid=null , $eventsId=null ) {		$this->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';	}		}
 |