<?php
/**
* 关键数据查询
*/
defined('IN_WEB') or die('Include Error!');

class Keydata
{
	
	private $_payBlackList; //支付需要过滤的黑名单
	function __construct()
	{
        $this->_payBlackList['uid'] = oo::commonOprModel("config")->payWhiteList();
	}

	/**
	*	关键数据查询
	*	1 查询订单总数
	*	2 留存率: 次日留存 3日留存 7日留存 30日留存
	*	3 登陆玩家数和新增玩家数
	*/
	public function index($param)
	{
		$data = array('totalLogin' => 0, 'totalNew' => 0, 'totalPay' => 0, 'nextDayRetention' => 0, 'last3DayRetention' => 0, 'last8DayRetention' => 0, 'lastBroke' => 0, 'totalOrder' => 0);
		$paymentTable		= otable::summarylist();

		$lastDate = date('Ymd', strtotime('-1 day'));
		$keyDataKey = 'LASTKEYDATA:'.$lastDate;
		if( $ret = oo::commonOprRedis('common')->get($keyDataKey) ){
			die($ret);
		}

		$stime = strtotime('-1 day 0:0:1');
		$etime = strtotime('-1 day 23:59:59');

		//每日登陆玩家总数
		$infoLogin = oo::commonOprModel('statistics')->getOneLoginPlayer($stime, $etime);
		if ($infoLogin) {
			$data['totalLogin'] = $infoLogin['total'];
		}

		//每日新增总数
		$infoNew = oo::commonOprModel('statistics')->getOneNewPlayer($stime, $etime);
		if ($infoNew) {
			$data['totalNew'] = $infoNew['total'];
		}

		//每日成功订单总数 每日成功订单数额
		$blackUidArr = $this->_payBlackList['uid'];
		$blackUidStr = implode(',', $blackUidArr);
		$sqlPayment = " SELECT COUNT(id) AS c, SUM(sl_pusd) AS p FROM {$paymentTable} WHERE sl_pay_time >= {$stime} AND sl_pay_time <= {$etime} AND sl_uid NOT IN ({$blackUidStr}) ";

        $infoPayment = oo::commonOprDb('common')->getOne($sqlPayment, 1);
		if( $infoPayment ){
			$data['totalPay'] = intval($infoPayment['c']);
			$data['pusd'] = $infoPayment['p'];
		}

		//昨日的支付人数
        $sqlPaymentPerson = " SELECT COUNT(1) as uidNum FROM ( SELECT COUNT(sl_uid) AS uid FROM {$paymentTable} WHERE sl_pay_time >= {$stime} AND sl_pay_time <= {$etime} AND sl_uid NOT IN ({$blackUidStr}) GROUP BY sl_uid ) as aa";
		$infoPaymentPerson = oo::commonOprDb('common')->getOne($sqlPaymentPerson, 1);
		$data['totalPerson'] = intval($infoPaymentPerson['uidNum'] ?? 0);

		//昨日的订单数
        $sqlOrder = " SELECT COUNT(1) AS num FROM {$paymentTable} WHERE sl_order_time >= {$stime} AND sl_order_time <= {$etime} AND sl_uid NOT IN ( $blackUidStr ) ";
        $infoOrder = oo::commonOprDb('common')->getOne($sqlOrder, 1);
        $data['totalOrder'] = intval($infoOrder['num'] ?? 0);

        //昨日的破产率
        $brokeActId = 10211;
        $brokeKey = 'EVENT:'.$lastDate.':'.$brokeActId.'USER';

        $num = intval(oo::commonOprRedis('statistics')->sSize($brokeKey));
        $data['lastBroke'] = empty($data['totalLogin']) ? 0 : round($num / $data['totalLogin'], 4);

		//次日新增留存 比如今天29号 就计算28号的次日留存 那么新增玩家从27号算,
		$days1ago = date('Ymd', strtotime('-1 days'));
		$days2ago = date('Ymd', strtotime('-2 days'));
		$yesterdayPlayer = $this->getAllPlayer($days1ago, 2);//登陆玩家
		$last2daysPlayer = $this->getAllPlayer($days2ago, 1);//新增玩家
		$intersect1dayPlay = array_intersect($yesterdayPlayer, $last2daysPlayer);//交集玩家
		$data['nextDayRetention'] = empty(count($last2daysPlayer)) ? 0 : count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率
//		oo::logs()->debug3(array('days1ago111' => $days1ago, 'days2ago' => $days2ago, 'intersect1dayPlay' => count($intersect1dayPlay), 'last2daysPlayer' => count($last2daysPlayer), 'tempDay1Remain' => count($intersect1dayPlay) / count($last2daysPlayer)), 'remain.log');

		//3日新增留存
		$days3age = date('Ymd', strtotime('-4 days'));
		$last3daysPlayer = $this->getAllPlayer($days3age, 1);//新增玩家
		$intersect3dayPlay = array_intersect($yesterdayPlayer, $last3daysPlayer);//交集玩家
		$data['last3DayRetention'] = empty(count($last3daysPlayer)) ? 0 : count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率

		//7日新增留存
		$days8age = date('Ymd', strtotime('-8 days'));
		$last8daysPlayer = $this->getAllPlayer($days8age, 1);//新增玩家
		$intersect8dayPlay = array_intersect($yesterdayPlayer, $last8daysPlayer);//交集玩家
		$data['last8DayRetention'] = empty($last8daysPlayer) ? 0 : count($intersect8dayPlay) / count($last8daysPlayer);//

        //30日新增留存
        $days30age = date('Ymd', strtotime('-30 days'));
        $last30daysPlayer = $this->getAllPlayer($days30age, 1); //新增玩家
        $intersect30dayPlay = array_intersect($yesterdayPlayer, $last30daysPlayer);//交集玩家
        $data['last30DayRetention'] = empty(count($last30daysPlayer)) ? 0 : count($intersect30dayPlay) / count($last30daysPlayer);//

		//次日活跃留存
		$yesterdayLoginPlayer = $this->getAllPlayer($days1ago, 2);//登陆玩家
		$last2daysLoginPlayer = $this->getAllPlayer($days2ago, 2);//登陆玩家
		$intersect1dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last2daysLoginPlayer);//交集玩家
		$data['nextDayLoginRetention'] = empty(count($last2daysLoginPlayer)) ? 0 : count($intersect1dayLoginPlay) / count($last2daysLoginPlayer);//次日留存率

		//3日活跃留存
		$last3daysLoginPlayer = $this->getAllPlayer($days3age, 2);//登陆玩家
		$intersect3dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last3daysLoginPlayer);//交集玩家
		$data['last3DayLoginRetention'] = empty(count($last3daysLoginPlayer)) ? 0 : count($intersect3dayLoginPlay) / count($last3daysLoginPlayer);//3日留存率

		//7日活跃留存
		$last8daysLoginPlayer = $this->getAllPlayer($days8age, 2);//登陆玩家
		$intersect8dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last8daysLoginPlayer);//交集玩家
		$data['last8DayLoginRetention'] = empty(count($last8daysLoginPlayer)) ? 0 : count($intersect8dayLoginPlay) / count($last8daysLoginPlayer);//3日留存率

        //30日活跃留存
        $last30daysLoginPlayer = $this->getAllPlayer($days30age, 2);//登陆玩家
        $intersect30dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last30daysLoginPlayer);//交集玩家
        $data['last30DayLoginRetention'] = empty(count($last30daysLoginPlayer)) ? 0 : count($intersect30dayLoginPlay) / count($last30daysLoginPlayer);//30日留存率


		$ret = json_encode($data);

        oo::commonOprRedis('common')->setex($keyDataKey, $ret);
		die($ret);
	}

	/**
	*	计算所有玩家
	*	type 1 新注册 其他登陆
	*/
	protected function getAllPlayer($date, $type)
	{
		$total = oo::commonOprModel('statistics')->getAllPlayer($date, $type);
		return $total;
	}
}