php 统计代码

<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/8/13
 * Time: 11:15
 */

namespace console\controllers;

use Yii;
use yii\db\Query;

class GameStatController extends BaseController
{
    public $db = '';

    public function init(){
        parent::init();
        $this->db = Yii::$app->btbox_db;
    }

    /**
     * 生成游戏统计数据
     * @param string $time
     * @author:mzc
     * @date:2018/8/13 20:58
     * @return:
     */
    public function actionGenStat($time=''){
        try{
            $this->_genStat($time);
        }catch (\Exception $ex){
            self::repError($ex->getMessage());
        }
    }

    /**
     * 生成半年内游戏统计的数据
     * @author:mzc
     * @date:2018/8/13 20:58
     * @return:
     */
    public function actionGenHalfYear(){
        $time = strtotime('-6 month',time());//半年前的时间戳
        $time = strtotime(date('Y-m-d 00:00:00',$time));
        do{
            try{
                $this->_genStat($time);
            }catch (\Exception $ex){
                Yii::error('halfyear:'.date('Y-m-d',$time).':'.$ex->getMessage(),LOG_CATE_CRON);
            }
            $time = strtotime('+1 day',$time);
        }while (date('Ymd', $time) != date('Ymd', time()));
    }

    /**
     * 统计独代游戏每天的留存率
     * @param string $time
     * @author:mzc
     * @date:2018/8/14 14:20
     * @return:
     */
    public function actionGenRemain($time=''){
        try{
            $this->_genRemain($time);
            self::repSuccess('留存率生成成功');
        }catch(\Exception $ex){
            self::repError($ex->getMessage());
        }
    }

    /**
     * 统计半年内游戏每一天的留存率
     * @author:mzc
     * @date:2018/8/14 14:20
     * @return:
     */
    public function actionGenHalfYearRemain(){
        $time = strtotime('-6 month',time());//半年前的时间戳
        do{
            try{
                $this->_genRemain($time);
            }catch (\Exception $ex){
                Yii::error('halfyear-remain:'.date('Y-m-d',$time).':'.$ex->getMessage(),LOG_CATE_CRON);
            }
            $time = strtotime('+1 day',$time);
        }while (date('Ymd', $time) != date('Ymd', time()));
//        }while (date('Ymd', $time) != '20180216');
        self::repSuccess('留存率生成成功');
    }
    
    private function _genRemain($ctime=''){
        $db = $this->db;

        $time = strtotime(date('Y-m-d 00:00:00',time()));
        if(!empty($ctime)){
            $time = strtotime(date('Y-m-d 00:00:00',$ctime));
        }

        try{
            // 第一天注册的用户
            $preSevenDay = strtotime('-7 day', $time);
            list($stime, $etime) = $this->_getStartEndTime($preSevenDay);
            $regUserIds = $this->getNewAcounts($stime, $etime);

            // 前6天日期,次日登录的用户
            $preSixDay = strtotime('-6 day', $time);
            list($stime, $etime) = $this->_getStartEndTime($preSixDay);
            $secondLoginUids = $this->getActivity($stime, $etime);

            // 前3天日期,第三天登录的用户
            $preThreeDay = strtotime('-4 day', $time);
            list($stime, $etime) = $this->_getStartEndTime($preThreeDay);
            $threeLoginUids = $this->getActivity($stime, $etime);

            // 第7天登录的用户
            list($stime, $etime) = $this->_getStartEndTime($time);
            $sevendLoginUids = $this->getActivity($stime, $etime);

            $games = $this->getSoleGames();

            if(empty($games)) throw new \Exception("没有可统计的游戏");

            foreach($games as $one){
                $gameid = $one['id'];
                $nextdayremains = $threedaysremains = $sevendaysremains = 0;

                $regUserId = !empty($regUserIds[$gameid]) ? $regUserIds[$gameid] : 0;

                $secondLoginUid = !empty($secondLoginUids[$gameid]) ? $secondLoginUids[$gameid] : 0;
                $threeLoginUid = !empty($threeLoginUids[$gameid]) ? $threeLoginUids[$gameid] : 0;
                $sevendLoginUid = !empty($sevendLoginUids[$gameid]) ? $sevendLoginUids[$gameid] : 0;

                if($regUserId){
                    $nextdayremains = round($secondLoginUid/$regUserId,3);
                    $threedaysremains = round($threeLoginUid/$regUserId,3);
                    $sevendaysremains = round($sevendLoginUid/$regUserId,3);
                }

                $db->createCommand()->update('cy_game_summary_stat', [
                    'nextdayremains' => $nextdayremains,
                    'threedaysremains' => $threedaysremains,
                    'sevendaysremains' => $sevendaysremains
                ], [
                    'gameid'=>$gameid,
                    'date_at'=>$time
                ])->execute();
            }
        }catch (\Exception $ex){
            throw new \Exception($ex->getMessage());
        }
    }

    /**
     * 获取开始与结束时间
     * @param $time
     * @author:mzc
     * @date:2018/8/14 14:26
     * @return:
     */
    private function _getStartEndTime($time){
        $startTime = strtotime(date('Y-m-d 00:00:00'),time());
        $endTime = time();

        if(!empty($time)){
            $startTime = strtotime(date('Y-m-d 00:00:00',$time));
            $endTime = strtotime(date('Y-m-d 23:59:59',$time));
        }
        return [$startTime,$endTime];
    }

    /**
     * 判断当天该游戏是否有记录,没有添加,有先删除再添加
     * @param $time 时间戳
     * @author:mzc
     * @date:2018/8/13 11:19
     * @return:
     */
    private function _genStat($time=''){
        $db = $this->db;

        list($startTime,$endTime) = $this->_getStartEndTime($time);

        try{
            //1.查询游戏
            $games = $this->getGames();
            if(empty($games)) throw new \Exception("没有可统计的游戏");

            $newUsers = $this->getNewAcounts($startTime,$endTime);//2.新增账号
            list($totalDevices,$andriodNews,$iosNews) = $this->getNewDevices($startTime,$endTime); //3.新增设备
            $actives = $this->getActivity($startTime,$endTime);//3.获取活跃账号
            list($payMans,$payNums,$payTotals) = $this->getPay($startTime,$endTime); //4.付费人数,付费次数,总付费金额
            $ptbs = $this->getPtb($startTime,$endTime);//6.平台币金额

            list($newPayMans,$newPayNums,$newPayTotals) = $this->getNewIncreated($startTime,$endTime);//新增付费人数$newPayMans,新增付费次数$newPayNums,新增付费总金额$newPayTotals

            foreach($games as $one){
                $gameid = $one['id'];
                $newCounts = !empty($newUsers[$gameid]) ? $newUsers[$gameid] : 0;
                $newDevices = !empty($totalDevices[$gameid]) ? count($totalDevices[$gameid]) : 0;
                $andriodNew = !empty($andriodNews[$gameid]) ? count($andriodNews[$gameid]) : 0;
                $iosNew = !empty($iosNews[$gameid]) ? count($iosNews[$gameid]) : 0;
                $activity =  !empty($actives[$gameid]) ? $actives[$gameid] : 0;;
                $payMan = !empty($payMans[$gameid]) ? $payMans[$gameid] : 0;
                $payNum = !empty($payNums[$gameid]) ? $payNums[$gameid] : 0;
                $payAmount = !empty($payTotals[$gameid]) ? $payTotals[$gameid] : 0;
                $ptb = !empty($ptbs[$gameid]) ? $ptbs[$gameid] : 0;

                $newPayMan = !empty($newPayMans[$gameid]) ? $newPayMans[$gameid] : 0;
                $newPayNum = !empty($newPayNums[$gameid]) ? $newPayNums[$gameid] : 0;
                $newPayTotal = !empty($newPayTotals[$gameid]) ? $newPayTotals[$gameid] : 0;

                //有记录先删除再添加
                $exists = (new Query())->from('cy_game_summary_stat')
                    ->where(['between', 'date_at', $startTime, $endTime])
                    ->andWhere([ 'gameid'=>$gameid])->exists($db);

                if($exists){
                    $sql="DELETE FROM cy_game_summary_stat WHERE gameid = '".$gameid."' AND date_at BETWEEN ".$startTime." AND ".$endTime;
                    $db->createCommand($sql)->execute();
                }

                $datas[] = [
                    'gameid'=>$gameid,
                    'gamename'=>$one['name'],
                    'sumpaycount'=>$payNum,
                    'newsdevice'=>$newDevices,
                    'newsuser'=>$newCounts,
                    'sumpay'=>$payMan,
                    'active'=>$activity,
                    'sumpayamount'=>$payAmount,
                    'ptbamount'=>$ptb,
                    'date_at'=>$startTime,
                    'newspay'=>$newPayMan,
                    'newspaycount'=>$newPayNum,
                    'newspayamount'=>$newPayTotal,
                    'userandroid'=>$andriodNew,
                    'userios'=>$iosNew,
                ];
            }

            //3.判断当天该游戏是否有记录,没有添加,有修改对应数据
            if (!empty($datas)) {
                $column = array_keys($datas[0]);
                $db->createCommand()->batchInsert('cy_game_summary_stat', $column, $datas)->execute();
            }

            $msg = date('Y-m-d').':生成游戏统计数据成功';
            Yii::info($msg, LOG_CATE_CRON);
        }catch (\Exception $ex){
            throw new \Exception($ex->getMessage());
        }
    }

    /**
     * 获取游戏
     * @author:mzc
     * @date:2018/8/13 14:44
     * @return:
     */
    private  function getGames(){
        $db = $this->db;
        $result = (new Query())
            ->select('*')
            ->from('cy_game')
            ->where(['isdelete' => 0])
            ->all($db);
        return $result;
    }

    /**
     * 获取独代游戏
     * @author:mzc
     * @date:2018/8/14 14:11
     * @return:
     */
    private  function getSoleGames(){
        $db = $this->db;
        $result = (new Query())
            ->select('a.id,a.name')
            ->from('cy_game a')
            ->leftJoin('cy_business b','a.origin=b.id')
            ->where(['a.isdelete' => 0])
            ->where(['a.id' => 2])
            ->andWhere(['like','b.cpinfo','墨仙互娱'])
            ->all($db);

        return $result;
    }


    
    /**
     * 新增账号
     * @param $gameid
     * @param $startTime
     * @param $endTime
     * @author:mzc
     * @date:2018/8/13 15:09
     * @return:
     */
    private function getNewAcounts($startTime,$endTime){
        $db = $this->db;
        $result = (new Query())
            ->select('gameid,count(*) as num')
            ->from('cy_members')
            ->where(['between', 'reg_time', $startTime, $endTime])
            ->groupBy('gameid')
            ->all($db);
        $data = [];
        if(!empty($result)){
            $gameid = array_column($result,'gameid');
            $num = array_column($result,'num');
            $data = array_combine($gameid,$num);
        }
        return $data;
    }

    /**
     * 新增设备,andriod新增,ios新增
     * @param $startTime
     * @param $endTime
     * @author:mzc
     * @date:2018/8/13 15:09
     * @return:
     */
    private function getNewDevices($startTime,$endTime){
        $db = $this->db;
        $total = $andriodAdd = $iosAdd = [];

        $result = (new Query())
            ->select('id,gameid,imeil,device')
            ->from('cy_members')
            ->where(['between', 'reg_time', $startTime, $endTime])
            ->groupBy('gameid,imeil,device')
            ->all($db);

        if(!empty($result)){
            foreach($result as $v){
                $gameid = $v['gameid'];
                if ($v['device'] == 2) $andriodAdd[$gameid][] = $v['id'];
                if ($v['device'] == 3) $iosAdd[$gameid][] = $v['id'];
                $total[$gameid][] =  $v['id'];
            }
        }

        return [$total,$andriodAdd,$iosAdd];
    }

    /**
     * 获取活跃人数
     * @param $gameid
     * @param $startTime
     * @param $endTime
     * @author:mzc
     * @date:2018/8/13 15:45
     * @return:
     */
    private function getActivity($startTime,$endTime){
        $db = $this->db;
        $result = (new Query())
            ->select('gameid,count(distinct(userid)) as num')
            ->from('cy_logininfo')
            ->where(['between', 'login_time', $startTime, $endTime])
            ->groupBy('gameid')
            ->all($db);

        $data = [];
        if(!empty($result)){
            $gameid = array_column($result,'gameid');
            $num = array_column($result,'num');
            $data = array_combine($gameid,$num);
        }
        return $data;
    }

    /**
     * 付费人数,付费次数,付费总金额
     * @param $gameid
     * @param $startTime
     * @param $endTime
     * @param $usernames 用户
     * @author:mzc
     * @date:2018/8/13 15:54
     * @return:
     */
    private function getPay($startTime,$endTime,$usernames=[]){
        $db = $this->db;

        //付费人数,//付费次数
        $result = (new Query())
            ->select('gameid,count(distinct(username)) as payMan,count(*) as payNum,sum(amount) as payTotal')
            ->from('cy_pay_ok')
            ->where(['between', 'create_time', $startTime, $endTime])
            ->andFilterWhere(['in','username',$usernames])
            ->groupBy('gameid')
            ->all($db);

        $payMans = $payNums = $payTotals= [];
        if(!empty($result)){
            $gameid = array_column($result,'gameid');
            $payMan = array_column($result,'payMan');
            $payMans = array_combine($gameid,$payMan);

            $payNum = array_column($result,'payNum');
            $payNums = array_combine($gameid,$payNum);

            $payTotal = array_column($result,'payTotal');
            $payTotals = array_combine($gameid,$payTotal);

        }

        return [$payMans,$payNums,$payTotals];
    }


    /**
     * 获取平台币金额
     * @param $gameid
     * @param $startTime
     * @param $endTime
     * @author:mzc
     * @date:ct
     * @return:
     */
    private function getPtb($startTime,$endTime){
        $db = $this->db;
        $result = (new Query())
            ->select('gameid,sum(amount) as total')
            ->from('cy_pay')
            ->where(['between', 'create_time', $startTime, $endTime])
            ->andWhere(['status' => 1, 'paytype' => 'ptb'])
            ->groupBy('gameid')
            ->all($db);

        $data = [];
        if(!empty($result)){
            $gameid = array_column($result,'gameid');
            $num = array_column($result,'total');
            $data = array_combine($gameid,$num);
        }
        return $data;
    }

    /**
     * 获取新增付费人数,新增付费次数,新增付费总金额
     * @param $gameid
     * @param $startTime
     * @param $endTime
     * @author:mzc
     * @date:2018/8/13 16:58
     * @return:
     */
    private function getNewIncreated($startTime,$endTime){
        $db = $this->db;

        //获取今日新增且有付费的用户
        $usernames = (new Query())
            ->select('distinct(a.username) as username')
            ->from('cy_pay_ok a')
            ->leftJoin('cy_members b','b.username = a.username')
            ->where(['between', 'a.create_time', $startTime, $endTime])
            ->andWhere(['between', 'b.reg_time', $startTime, $endTime])
            ->column($db);

        list($newPayMan,$newPayNum,$newPayTotal) = $this->getPay($startTime,$endTime,$usernames);

        return [$newPayMan,$newPayNum,$newPayTotal];
    }
}
<?php
/**
 * Created by mxhy.
 * 
 * @FileName : BaseController.php
 * @Author : yzm <[email protected]>
 * @DateTime : 2018/1/20 0020-01-20 12:16 
 */


namespace console\controllers;

use Yii;
use yii\console\Controller;

class BaseController extends Controller
{

    protected static $runTime = null;
    protected $pageSize = 1000; // 每次请求多少数据

    function actions()
    {
        self::$runTime = time();

        error_reporting(E_ALL);
        ini_set("max_execution_time", "3600");
        ini_set("memory_limit", '2048M');
        set_time_limit(0);

        return parent::actions(); // TODO: Change the autogenerated stub
    }

    /**
     * 错误响应.
     *
     * @param $data
     */
    public static function repError($data = 'FAIL')
    {
        $msg = is_array($data) ? var_export($data, true) : $data;
        Yii::warning($msg, LOG_CATE_CRON);
        echo $msg;
        exit(1);

    }

    /**
     * 成功响应.
     *
     * @param $data
     */
    public static function repSuccess($data = 'SUCCESS')
    {
        $msg = is_array($data) ? var_export($data, true) : $data;
        Yii::info($msg, LOG_CATE_CRON);
        echo $msg;

        exit(0);
    }
}

猜你喜欢

转载自blog.csdn.net/mengzuchao/article/details/81672150