You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1129 lines
21 KiB
PHTML

5 years ago
<?php
/**
* Created by PhpStorm.
* User: xmy 280564871@qq.com
* Date: 2017/4/27
* Time: 9:33
*/
namespace Open\Controller;
use Admin\Model\SpendModel;
use Admin\Model\UserPlayModel;
use Open\Model\GameModel;
use Open\Model\UserLoginRecordModel;
class StatsController extends CenterController{
public function _initialize()
{
$this->title = "概览";
$this->p_title = "管理中心";
$this->p_url = U('Stats/overview');
parent::_initialize(); // TODO: Change the autogenerated stub
}
/**
* 概览
* author: xmy 280564871@qq.com
*/
public function overview(){
$UserPlay = new UserPlayModel();
//累计玩家
$total_player = $UserPlay->getTotalPlayerOfOpen(['g.developers'=>UID]);
$this->assign("total_player",$total_player);
//付费玩家
$Spend = new SpendModel();
$spend_user = $Spend->countSpendUserOfOpen(['g.developers'=>UID,'s.pay_status'=>1]);
$this->assign("spend_user",$spend_user);
//累计流水
$total_spend = $Spend->totalSpend(["g.developers"=>UID]);
$this->assign("total_spend",$total_spend);
//实时活跃
$today = strtotime("today");
$today_active_user = $UserPlay->getTotalPlayerOfOpen(["g.developers"=>UID,'p.play_time'=>['between',[$today,$today+86400-1]]]);
$this->assign("today_active_user",$today_active_user);
//实时流水
$today_spend = $Spend->totalSpend(["g.developers"=>UID,'s.pay_time'=>['between',[$today,$today+86400-1]]]);
$this->assign("today_spend",$today_spend);
//游戏数量
$Game = new GameModel();
$game_num = $Game->getGameNum(['developers'=>UID]);
$this->assign("game_num",$game_num);
//已上线
$online_game = $Game->getGameNum(['developers'=>UID,'online_status'=>1,'apply_status'=>1]);
$this->assign("online_game",$online_game);
//已下线
$down_game = $Game->getGameNum(['developers'=>UID,'online_status'=>0,'apply_status'=>1]);
$this->assign("down_game",$down_game);
//审核中
$check_game = $Game->getGameNum(['developers'=>UID,'apply_status'=>0]);
$this->assign("check_game",$check_game);
//未通过
$reject_game = $Game->getGameNum(['developers'=>UID,'apply_status'=>2]);
$this->assign("reject_game",$reject_game);
//数据详情
//$this->detail();
$this->indicators();
$this->display();
}
/**
* 关键指标
* @author 鹿文学
*/
public function indicators() {
$start = empty(I('time_start')) ? strtotime("today") - 6 * 86400 : strtotime(I('time_start'));
$end = empty(I("time_end")) ? strtotime("today") : strtotime(I('time_end'));
$start_str = date("Y-m-d",$start);
$end_str = date("Y-m-d",$end);
$game_id = I('post.game_id');
$Record = new UserLoginRecordModel();
//新玩家
$detail['add_user'] = $data['newUsers'] = $Record->get_news_player($start_str,$end_str, UID, $game_id);
//活跃玩家
$map['d.time'] = ['between',[$start_str,$end_str]];
$detail['active_user'] = $data['activeUsers'] = $Record->getActivePlayer($map,UID,$game_id);
//老用户
$data['oldUsers'] = [];
//付费玩家
$Spend = new SpendModel();
$detail['payer_num'] = $data['payUsers'] = $Spend->getPayerNum($map,UID,$game_id);
//新付费玩家
$detail['new_payer_num'] = $data['newPayUsers'] = $Spend->getNewPayerNum($start_str,$end_str,UID,$game_id);
//每日流水
$s_map = $map;
$s_map['s.game_id'] = $game_id;
$detail['spend'] = $data['usersIncome'] = $Spend->getOpenSpend($map,UID,$game_id);
//ARPU
$data['usersArpu'] = [];
//ARPPU
$data['usersArppu'] = [];
//付费率
$data['usersPayRate'] = [];
//老付费玩家
$data['oldPayUsers'] = [];
//1 3 7日留存
$keep_user = $Record->get_keep_player($start,$end,UID,$game_id,[1,3,7]);
$detail['keep_user'] = $keep_user['1RatentionRate'];
$data = array_merge($data,$keep_user);
$res = [];
foreach ($data as $key=>$value){
$value = array_column($value,'num');
$i = 0;
for ($time = $start; $time <= $end; $time += 86400) {
$time_k = date("Y-m-d",$time);
switch ($key){
case "oldUsers"://老用户
$res[$key][$time_k] = !is_nan($res['activeUsers'][$time_k] - $res['newUsers'][$time_k])? $res['activeUsers'][$time_k] - $res['newUsers'][$time_k]:0;
break;
case "usersArpu"://ARPU
$res[$key][$time_k] = !is_nan(round($res['usersIncome'][$time_k] / $res['activeUsers'][$time_k],2))?round($res['usersIncome'][$time_k] / $res['activeUsers'][$time_k],2):0;
break;
case "usersArppu"://ARPU
$res[$key][$time_k] = !is_nan(round($res['usersIncome'][$time_k] / $res['payUsers'][$time_k],2))?round($res['usersIncome'][$time_k] / $res['payUsers'][$time_k],2):0;
break;
case "usersPayRate"://付费率
$res[$key][$time_k] = !is_nan(round($res['payUsers'][$time_k] / $res['activeUsers'][$time_k]*100,2))?round($res['payUsers'][$time_k] / $res['activeUsers'][$time_k]*100,2):0;
break;
case "oldPayUsers"://老付费玩家
$res[$key][$time_k] = !is_nan($res['payUsers'][$time_k] - $res['newPayUsers'][$time_k])?$res['payUsers'][$time_k] - $res['newPayUsers'][$time_k]:0;
break;
case "1RatentionRate":
$res[$key][$time_k] =!is_nan(round($value[$i] / $res['newUsers'][$time_k] * 100,2))?round($value[$i++] / $res['newUsers'][$time_k] * 100,2):0;
break;
case "3RatentionRate":
$res[$key][$time_k] = !is_nan(round($value[$i] / $res['newUsers'][$time_k] * 100,2))?round($value[$i++] / $res['newUsers'][$time_k] * 100,2):0;
break;
case "7RatentionRate":
$res[$key][$time_k] = !is_nan(round($value[$i] / $res['newUsers'][$time_k] * 100,2))? round($value[$i++] / $res['newUsers'][$time_k] * 100,2):0;
break;
default:
$res[$key][$time_k] = $value[$i++];
}
}
}
$this->assign("json_data",json_encode($res));
$this->data_detail_list($start_str,$end_str,$detail,$game_id);
}
/**
* 详细数据
* @author 鹿文学
*/
public function data_detail_list($last_week,$today,$data,$game_id='') {
$Spend = new SpendModel();
//累计付费玩家
$data['payer_num_total'] = $Spend->getTotalPayerNum($last_week,$today,UID);
//详情列表数据
foreach ($data as $key => $value){
foreach ($value as $k => $v){
$time = date("Y-m-d",strtotime($today)-(count($value)-$k-1)*86400);
$result[$time][$key] = $v['num'];
}
}
krsort($result);
$this->assign('detail_data_lists',$result);
}
/*
public function data_detail($last_week,$today) {
//新增玩家
$map['d.time'] = ['between',[$last_week ,$today]];
$UserPlay = new UserLoginRecordModel();
$data['add_user'] = $UserPlay->get_news_player($last_week,$today,UID);
//活跃玩家
$data['active_user'] = $UserPlay->getActivePlayer($map,UID);
//老用户
// $data['old_user'] = $UserPlay->getOldPlayer($last_week,$today,UID);
//1日留存率
$data['keep_user'] = $UserPlay->getKeepPlayer($last_week,$today,UID)["1RatentionRate"];
//流水
$Spend = new SpendModel();
$data['spend'] = $Spend->getOpenSpend($map,UID);
//付费玩家
$data['payer_num'] = $Spend->getPayerNum($map,UID);
//新付费玩家
$data['new_payer_num'] = $Spend->getNewPayerNum($last_week,$today,UID);
//累计付费玩家
$data['payer_num_total'] = $Spend->getTotalPayerNum($last_week,$today,UID);
//详情列表数据
foreach ($data as $key => $value){
foreach ($value as $k => $v){
$time = date("Y-m-d",strtotime("today")-(6-$k)*86400);
$result[$time][$key] = $v['num'];
}
}
krsort($result);
$this->assign('detail_data_lists',$result);
}
*/
public function detail(){
//最近七天
$last_week = date("Y-m-d",strtotime("today")-6*86400);
$today = date("Y-m-d",strtotime("today"));
//新增玩家
$map['d.time'] = ['between',[$last_week ,$today]];
$UserPlay = new UserLoginRecordModel();
$data['add_user'] = $UserPlay->getAddPlayer($last_week,$today,UID);
//活跃玩家
$data['active_user'] = $UserPlay->getActivePlayer($map,UID);
//老用户
// $data['old_user'] = $UserPlay->getOldPlayer($last_week,$today,UID);
//1日留存率
$data['keep_user'] = $UserPlay->getKeepPlayer($last_week,$today,UID)["1RatentionRate"];
//流水
$Spend = new SpendModel();
$data['spend'] = $Spend->getOpenSpend($map,UID);
//付费玩家
$data['payer_num'] = $Spend->getPayerNum($map,UID);
//新付费玩家
$data['new_payer_num'] = $Spend->getNewPayerNum($last_week,$today,UID);
//累计付费玩家
$data['payer_num_total'] = $Spend->getTotalPayerNum($last_week,$today,UID);
//详情列表数据
foreach ($data as $key => $value){
foreach ($value as $k => $v){
$time = date("Y-m-d",strtotime("today")-(6-$k)*86400);
$result[$time][$key] = $v['num'];
}
}
krsort($result);
$this->assign('detail_data_lists',$result);
$this->chart();
}
/**
* 图表
* author: xmy 280564871@qq.com
*/
public function chart()
{
$start = empty(I('time_start')) ? strtotime("today") - 6 * 86400 : strtotime(I('time_start'));
$end = empty(I("time_end")) ? strtotime("today") : strtotime(I('time_end'));
$start_str = date("Y-m-d",$start);
$end_str = date("Y-m-d",$end);
$game_id = I('post.game_id');
$Record = new UserLoginRecordModel();
//新玩家
$data['newUsers'] = $Record->getAddPlayer($start_str,$end_str, UID, $game_id);
//活跃玩家
$map['d.time'] = ['between',[$start_str,$end_str]];
$data['activeUsers'] = $Record->getActivePlayer($map,UID,$game_id);
//老用户
$data['oldUsers'] = [];
//付费玩家
$Spend = new SpendModel();
$data['payUsers'] = $Spend->getPayerNum($map,UID,$game_id);
//新付费玩家
$data['newPayUsers'] = $Spend->getNewPayerNum($start_str,$end_str,UID,$game_id);
//每日流水
$s_map = $map;
$s_map['s.game_id'] = $game_id;
$data['usersIncome'] = $Spend->getOpenSpend($map,UID);
//ARPU
$data['usersArpu'] = [];
//ARPPU
$data['usersArppu'] = [];
//付费率
$data['usersPayRate'] = [];
//老付费玩家
$data['oldPayUsers'] = [];
//1 3 7日留存
$keep_user = $Record->getKeepPlayer($start_str,$end_str,UID,$game_id,[1,3,7]);
$data = array_merge($data,$keep_user);
$res = [];
foreach ($data as $key=>$value){
$value = array_column($value,'num');
$i = 0;
for ($time = $start; $time <= $end; $time += 86400) {
$time_k = date("Y-m-d",$time);
switch ($key){
case "oldUsers"://老用户
$res[$key][$time_k] = !is_nan($res['activeUsers'][$time_k] - $res['newUsers'][$time_k])? $res['activeUsers'][$time_k] - $res['newUsers'][$time_k]:0;
break;
case "usersArpu"://ARPU
$res[$key][$time_k] = !is_nan(round($res['usersIncome'][$time_k] / $res['activeUsers'][$time_k],2))?round($res['usersIncome'][$time_k] / $res['activeUsers'][$time_k],2):0;
break;
case "usersArppu"://ARPU
$res[$key][$time_k] = !is_nan(round($res['usersIncome'][$time_k] / $res['payUsers'][$time_k],2))?round($res['usersIncome'][$time_k] / $res['payUsers'][$time_k],2):0;
break;
case "usersPayRate"://付费率
$res[$key][$time_k] = !is_nan(round($res['payUsers'][$time_k] / $res['activeUsers'][$time_k]*100,2))?round($res['payUsers'][$time_k] / $res['activeUsers'][$time_k]*100,2):0;
break;
case "oldPayUsers"://老付费玩家
$res[$key][$time_k] = !is_nan($res['payUsers'][$time_k] - $res['newPayUsers'][$time_k])?$res['payUsers'][$time_k] - $res['newPayUsers'][$time_k]:0;
break;
case "1RatentionRate":
$res[$key][$time_k] =!is_nan(round($value[$i++] / $res['newUsers'][$time_k] * 100,2))?round($value[$i++] / $res['newUsers'][$time_k] * 100,2):0;
break;
case "3RatentionRate":
$res[$key][$time_k] = !is_nan(round($value[$i++] / $res['newUsers'][$time_k] * 100,2))?round($value[$i++] / $res['newUsers'][$time_k] * 100,2):0;
break;
case "7RatentionRate":
$res[$key][$time_k] = !is_nan(round($value[$i++] / $res['newUsers'][$time_k] * 100,2))? round($value[$i++] / $res['newUsers'][$time_k] * 100,2):0;
break;
default:
$res[$key][$time_k] = $value[$i++];
}
}
}
$this->assign("json_data",json_encode($res));
}
public function retention($p=1){
$this->title = "留存分析";
$start = empty(I('time_start')) ? strtotime("today") - 6 * 86400 : strtotime(I('time_start'));
$end = empty(I("time_end")) ? strtotime("today") : strtotime(I('time_end'));
$game_id = I('game_id');
$start_str = date("Y-m-d",$start);
$end_str = date("Y-m-d",$end);
$Record = new UserLoginRecordModel();
//留存
$day = [1,2,3,7,10,14,15,30];
//$keep = $Record->getKeepPlayer($start_str,$end_str,UID,$game_id,$day);
$keep = $Record->get_keep_player($start,$end,UID,$game_id,$day);
//新增玩家
//$data['newUsers'] = $Record->getAddPlayer($start_str,$end_str, UID, $game_id);
$data['newUsers'] = $Record->get_news_player($start_str,$end_str, UID, $game_id);
$data = array_merge($data,$keep);
foreach ($data as $key=>$value){
$value = array_column($value,'num');
$i = 0;
for ($time = $start; $time <= $end; $time += 86400) {
$time_k = date("Y-m-d",$time);
if($key == "newUsers"){
//表格数据显示
$result[$time_k][$key] = $value[$i];
//统计图
$res[$key][$time_k] = $value[$i];
}else{
$key = str_replace("RatentionRate","",$key);
//表格数据显示
$result[$time_k][$key] = round($value[$i] / $res['newUsers'][$time_k] * 100, 2);
//统计图
$res[$key][$time_k] = $result[$time_k][$key];
}
$i++;
}
}
krsort($result);
$this->assign("json_data",json_encode($res));
$this->assign("data",$result);
$this->display();
}
public function loss(){
$this->title = "流失分析";
$start=get_lastweek_name(6);
$end=date('Y-m-d');
$this->assign('start',$start);
$this->assign('end',$end);
$result=$this->loss_pic($_REQUEST);
foreach ($result['day'] as $key => $value) {
$res['lossplayer']['loss'][$value]=$result['loss_count'][$key];
$res['lossplayer']['lossrate'][$value]=$result['loss_rate'][$key];
}
$money_arr=array(
">¥2000","¥1000~2000","¥600~1000","¥200~600","¥100~200","¥40~100","¥20~40","¥10~20","¥2~$10","<¥2",
);
foreach ($money_arr as $key => $value) {
$res['lossmoney'][$value]=$result['loss_money'][$key];
}
$times_arr=array(
">50次","41~50次","31~40次","21~30次","11~20次","6~10次","5次","4次","3次","2次","1次","未付费",
);
foreach ($times_arr as $key => $value) {
$res['losstimes'][$value]=$result['loss_times'][$key];
}
$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=$this->every_day(7);
$dd=prDates($defTimeS,$defTimeE);
}
if(isset($para['game_id'])){
$map['r.game_id']=$para['game_id'];
$map1['r.game_id']=$para['game_id'];
}
if(isset($para['channel_id'])&&$para['channel_id']!=""){
if($para['channel_id']==2){
$d=7;
}else{
$d=3;
}
}else{
$d=3;
}
$limitI=count($dd);
$Record = new UserLoginRecordModel();
for($i=0;$i<$limitI;$i++){
$start=$this->get_time($dd[$i],$d);
$end=$start+24*60*60-1;
$map['login_time']=array('between',array($start,$end));
$map['developers']=UID;
$logins=$Record->getPlayers($map,UID);
if($logins==null){
$loss=null;
}else{
$loss=null;
foreach ($logins as $key => $value) {
$start=date("Y-m-d", $value['login_time']+24*60*60);
$start=$this->get_time($start,0);
$end=$start+24*60*60*$d;
$map1['login_time']=array('between',array($start,$end));
$map1['user_id']=$value['user_id'];
$map1['developers']=UID;
$result1=$Record->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'];
}
}
$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]
* @return [type] [description]
*/
function loss_pic2($data){
$Spend=new SpendModel();
foreach ($data as $key => $value) {
$list[$key]['user_id']=$value;
$list[$key]['amount']=$Spend->totalSpend($list[$key]);
}
foreach ($list as $k => $v) {
if($v['amount']<2){
$two[]=$v;
}elseif($v['amount']<10){
$ten[]=$v;
}elseif($v['amount']<20){
$twenty[]=$v;
}elseif($v['amount']<40){
$forty[]=$v;
}elseif($v['amount']<100){
$hundred[]=$v;
}elseif($v['amount']<200){
$thundred[]=$v;
}elseif($v['amount']<600){
$shundred[]=$v;
}elseif($v['amount']<1000){
$thousand[]=$v;
}elseif($v['amount']<2000){
$tthousand[]=$v;
}else{
$thousands[]=$v;
}
}
$result=[count($thousands),count($tthousand),count($thousand),count($shundred),count($thundred),count($hundred),count($forty),count($twenty),count($ten),count($two)];
return $result;
}
/**
* 流失用户消费次数分析,包括不同次数所占人数和比例
* @param [type] $data [description]
* @return [type] [description]
*/
public function loss_pic3($data){
$Spend=new SpendModel();
foreach ($data as $key => $value) {
$list[$key]['user_id']=$value;
$list[$key]['count']=$Spend->totalSpendTimes($list[$key]);
}
foreach ($list as $k => $v) {
if($v['count']==0){
$zero[]=$v;
}elseif($v['count']==1){
$one[]=$v;
}elseif($v['count']==2){
$two[]=$v;
}elseif($v['count']==3){
$three[]=$v;
}elseif($v['count']==4){
$four[]=$v;
}elseif($v['count']==5){
$five[]=$v;
}elseif($v['count']<11){
$ten[]=$v;
}elseif($v['count']<21){
$twenty[]=$v;
}elseif($v['count']<31){
$thirty[]=$v;
}elseif($v['count']<41){
$forty[]=$v;
}elseif($v['count']<51){
$fifty[]=$v;
}else{
$fiftys[]=$v;
}
}
$result=[count($fiftys),count($fifty),count($forty),count($thirty),count($twenty),count($ten),count($five),count($four),count($three),count($two),count($one),count($zero)];
return $result;
}
/**
* [get_time 通过日期获得时间戳]
* @param [type] $date [description]
* @return [type] [int]
*/
private function get_time($date,$d){
$date= explode("-",$date);
$year=$date[0];
$month=$date[1];
$day=$date[2];
$start=mktime(0,0,0,$month,$day,$year)-$d*24*60*60;
return $start;
}
/**
* [every_day 获取日期]
* @param integer $m [description]
* @return [type] [array]
*/
private function every_day($m=7){
$time=array();
for ($i=$m-1; $i >=0 ; $i--) {
$time[]=date('Y-m-d',mktime(0,0,0,date('m'),date('d')-$i,date('Y')));
}
return $time;
}
}