diff --git a/Application/Admin/Controller/StatController.class.php b/Application/Admin/Controller/StatController.class.php index 3f3ee2da9..a9a06b3ea 100644 --- a/Application/Admin/Controller/StatController.class.php +++ b/Application/Admin/Controller/StatController.class.php @@ -229,81 +229,92 @@ class StatController extends ThinkController $this->assign("json_data",json_encode($res)); $this->display(); } + //流失率分析 public function loss_pic($para){ - if(isset($para['time_start'])&&isset($para['time_end'])&&$para['time_start']!==null&&$para['time_end']!==null){ - $dd=prDates($para['time_start'],$para['time_end']); - $day=$dd; - $this->assign('tt',array_chunk($dd,1)); - }else{ - $defTimeE=date("Y-m-d",time()); - $defTimeS=date("Y-m-d",time()-24*60*60*6); - $day=every_day(7); - $dd=prDates($defTimeS,$defTimeE); + if (!empty($para['time_start']) && !empty($para['time_end'])) { + $days = prDates($para['time_start'],$para['time_end']); + $day = $days; + $this->assign('tt',array_chunk($days,1)); + } else { + $defTimeE = date("Y-m-d",time()); + $defTimeS = date("Y-m-d",time() - 24*60*60*6); + $day = every_day(7); + $days = prDates($defTimeS,$defTimeE); } - if(isset($para['game_id'])){ + if (isset($para['game_id'])) { $map['r.fgame_id']=$para['game_id']; $map1['r.fgame_id']=$para['game_id']; } - if(isset($para['channel_id'])&&$para['channel_id']!=""){ - if($para['channel_id']==2){ - $d=7; - }else{ - $d=3; + if (!empty($para['channel_id'])) { + if ($para['channel_id'] == 2 ) { + $continueDay = 7; + } else { + $continueDay = 3; } }else{ - $d=3; + $continueDay = 3;//3天不登录表示玩家已流失 } - $limitI=count($dd); $usermodel = D('User'); - for($i=0;$i<$limitI;$i++){ - $start=$this->get_time($dd[$i],$d); - $end=$start+24*60*60-1; - $map['r.register_time']=array('between',array($start,$end)); - if(isset($para['promote_id'])&&$para['promote_id']!=""){ - $map['r.promote_id']=$para['promote_id']; - } - $logins=$usermodel->getPlayers($map); - if($logins==null){ - $loss=null; - }else{ - $loss=null; - foreach ($logins as $key => $value) { - $start=date("Y-m-d", $value['register_time']+24*60*60); - $start=$this->get_time($start,0); - $end=$start+24*60*60*$d; - $map1['r.login_time']=array('between',array($start,$end)); - $map1['r.user_id']=$value['id']; - if(isset($para['promote_id'])&&$para['promote_id']!=""){ - $map1['promote_id']=$para['promote_id']; - } - $result1=$usermodel->findPlayer($map1); - if($result1==null){ - $loss[]=$logins[$key]; - } - } - } - if($loss!=null){ - $loser[]=$loss; - } - $loss_count[]=count($loss); - $loss_rate[]=count($loss)/count($logins)*100?sprintf("%.2f",count($loss)/count($logins)*100):0; - } - foreach ($loser as $key => $value) { - foreach ($value as $k => $v) { - $losers[]=$v['user_id']; + + //获取这个时间段内注册的玩家 + $start = $this->get_time(current($days), $continueDay); + $end = $this->get_time(end($days), $continueDay) + 86399;; + $map['register_time']=array('between',array($start, $end)); + if (isset($para['promote_id']) && $para['promote_id']!="") { + $map['promote_id']=$para['promote_id']; + } + $players = $usermodel->getUserList($map, "GROUP_CONCAT(DISTINCT id) as user_ids, + FROM_UNIXTIME(register_time+{$continueDay}*86400, '%Y-%m-%d') as register_date", "register_date"); + $players = array_column($players, 'user_ids', 'register_date'); + + //获取这段时间内有登录(未流失)的玩家 + $map1['r.login_time'] = array('exp', 'BETWEEN UNIX_TIMESTAMP( + FROM_UNIXTIME( + u.register_time + 86400, + "%Y-%m-%d" + ) +) +AND UNIX_TIMESTAMP( + FROM_UNIXTIME( + u.register_time + 86400, + "%Y-%m-%d" + ) +) + 86400 * ' . $continueDay); + + if (isset($para['promote_id'])&&$para['promote_id']!="") { + $map1['u.promote_id']=$para['promote_id']; + } + $map1['u.register_time'] = array('between',array($start, $end)); + $keepPlayers = $usermodel->getKeepPlayers($map1, $continueDay);// 3或7天内有登录的玩家 + $keepPlayers = array_column($keepPlayers, 'user_ids', 'register_date'); + + $loss_count = array();//流失玩家数量 + foreach ($days as $key => $date) { + $dateUserCount = isset($players[$date]) ? count(explode(",", $players[$date])) : 0; + $keepUserCount = isset($keepPlayers[$date]) ? count(explode(",", $keepPlayers[$date])) : 0; + $loss_count[$key] = $dateUserCount - $keepUserCount;//流失数量 + + if ($dateUserCount) { + $loss_rate[] = sprintf("%.2f",($loss_count[$key]/$dateUserCount) * 100);//流失率 + } else { + $loss_rate[] = 0; } } - $data2=$this->loss_pic2($losers); - $data3=$this->loss_pic3($losers); - $result['day']=$day; - $result['loss_count']=$loss_count; - $result['loss_rate']=$loss_rate; - $result['loss_money']=$data2; - $result['loss_times']=$data3; + $losers = array_filter($players, function ($item) use ($keepPlayers) { + return !in_array($item, $keepPlayers); + }); + $losers = array_values($losers);//流失玩家id集合 + $data2 = $this->loss_pic2($losers); + $data3 = $this->loss_pic3($losers); + $result['day'] = $day;//日期 + $result['loss_count'] = $loss_count;//流失数量 + $result['loss_rate'] = $loss_rate;//流失率 + $result['loss_money'] = $data2;//流失金额 + $result['loss_times'] = $data3;//流失次数 return $result; - } + /** * 流失用户消费金额分析,包括不同等级的人数和所占比例 * @param [type] $data [description] diff --git a/Application/Admin/Model/UserModel.class.php b/Application/Admin/Model/UserModel.class.php index 489b6a2db..fbb262426 100644 --- a/Application/Admin/Model/UserModel.class.php +++ b/Application/Admin/Model/UserModel.class.php @@ -2073,6 +2073,35 @@ class UserModel extends Model{ return $data; } + /** + * 获取用户列表 + */ + public function getUserList($param, $field = "*", $group = "") + { + $result = $this->where($param) + ->field($field) + ->group($group) + ->select(); + return $result; + } + + /** + * 获取未流失的玩家 + * @param $day int 几天算玩家流失 + */ + public function getKeepPlayers($map = '', $day) + { + $map['lpuid']=0; + $data = M('user_login_record','tab_') + ->alias("r") + ->field("GROUP_CONCAT(DISTINCT u.id) as user_ids,FROM_UNIXTIME(u.register_time+{$day}*86400, '%Y-%m-%d') as register_date") + ->join("right join tab_user as u on r.user_id = u.id") + ->group("r.user_id") + ->where($map) + ->select(); + return $data; + } + }