123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- <?php
- namespace 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';
- }
-
-
- }
|