| <?php  | 
|   | 
| namespace Report;  | 
|   | 
| include_once '/Common/CommFunc.php';  | 
| include_once '/Common/Logging.php';  | 
| include_once "/db/DBOper.php";  | 
|   | 
| function OnExportRep()  | 
| {  | 
|     $curDate = getdate();  | 
|     // $dateStr = $curDate['year'] . "-" . $curDate['mon'] . "-" . $curDate['mday'];  | 
|     $curHour = $curDate['hours'];  | 
|     // 每天x点固定检查导出报表  | 
|     if ($curHour != 1) {  | 
|         return;  | 
|     }  | 
|     $AllChannel = \CommFunc\GetAllChannel();  | 
|     for ($i = 0; $i < count($AllChannel); $i++) {  | 
|         $Channel = $AllChannel[$i];  | 
|         CheckAndExportDailyReport($Channel);  | 
|         CheckAndExportFirstKeepReport($Channel);  | 
|     }  | 
| }  | 
|   | 
| /**检查并导出每日报表 */  | 
| function CheckAndExportDailyReport($Channel)  | 
| {  | 
|     if (!\DBOper\FindOneSort("DailyReport", array("Channel" => $Channel), $retInfo, array("YMD" => 1), array("YMD" => -1))) {  | 
|         return;  | 
|     }  | 
|     $StartYMDTime = 0; // 需要导出的起始日期时间戳  | 
|     if (isset($retInfo)) {  | 
|         $lastYMD = $retInfo["YMD"]; // 最后一次导出的报表日期  | 
|         $StartYMDTime = strtotime("+1 day", strtotime($lastYMD)); // 从+1天开始导出  | 
|         \Logging\LogInfo("ExportDailyReport Channel:" . $Channel . " lastYMD:" . $lastYMD . " StartYMDTime:" . date("Y-m-d", $StartYMDTime));  | 
|     } else {  | 
|         // 取出最早的首登日期  | 
|         if (!\DBOper\FindOneSort("AccountFirstLogin", array("Channel" => $Channel), $retInfo, array("CreateYMD" => 1), array("CreateYMD" => 1))) {  | 
|             return;  | 
|         }  | 
|         if (!isset($retInfo)) {  | 
|             \Logging\LogInfo("ExportDailyReport AccountFirstLogin 还没有数据,不用导出! Channel:" . $Channel);  | 
|             return;  | 
|         }  | 
|         $StartYMDTime = strtotime($retInfo["CreateYMD"]);  | 
|         \Logging\LogInfo("ExportDailyReport Channel:" . $Channel . " AccountFirstLogin StartYMDTime:" . date("Y-m-d", $StartYMDTime));  | 
|     }  | 
|     if (!$StartYMDTime) {  | 
|         return;  | 
|     }  | 
|   | 
|     $EndYMDTime = strtotime("-1 day", strtotime(date("Y-m-d"))); // 只导出到昨天  | 
|     $diffSeconds = $EndYMDTime - $StartYMDTime;  | 
|     $diffDays = floor($diffSeconds / (3600 * 24)) + 1;  | 
|     if ($diffDays <= 0) {  | 
|         \Logging\LogInfo("【 " . $Channel . " 】不需要导出每日报表! StartYMDTime:" . date("Y-m-d", $StartYMDTime));  | 
|         return;  | 
|     }  | 
|   | 
|     \Logging\LogInfo("===== 开始导出每日报表 【" . $Channel . "】 =====");  | 
|     \Logging\LogInfo("StartYMDTime:" . $StartYMDTime . " " . date("Y-m-d", $StartYMDTime));  | 
|   | 
|     $batchInsDayActive = array();  | 
|     while ($StartYMDTime <= $EndYMDTime && $diffDays >= 0) {  | 
|         $diffDays -= 1;  | 
|         $exportActiveYMD = date("Y-m-d", $StartYMDTime);  | 
|         $repArray = StatDailyReport($Channel, $exportActiveYMD);  | 
|   | 
|         array_push($batchInsDayActive, $repArray);  | 
|   | 
|         $StartYMDTime = strtotime("+1 day", $StartYMDTime);  | 
|     }  | 
|   | 
|     if (count($batchInsDayActive) > 0) {  | 
|         \DBOper\BatchInsert("DailyReport", $batchInsDayActive);  | 
|     }  | 
|     \Logging\LogInfo("==============================================");  | 
| }  | 
|   | 
| /**  | 
|  * 统计日报表  | 
|  * @param string $Channel  | 
|  * @param string $YMD 要统计的yyyy-MM-dd  | 
|  */  | 
| function StatDailyReport($Channel, $YMD)  | 
| {  | 
|     \Logging\LogInfo("=== 统计: " . $YMD);  | 
|     $DAU = \DBOper\Count("AccountDayActive", array("Channel" => $Channel, "ActiveYMD" => $YMD));  | 
|     \Logging\LogInfo(" 日活跃用户数 DAU:" . $DAU);  | 
|   | 
|     $DNU = \DBOper\Count("AccountFirstLogin", array("Channel" => $Channel, "CreateYMD" => $YMD));  | 
|     \Logging\LogInfo(" 日新增用户数 DNU:" . $DNU);  | 
|   | 
|     \DBOper\Find("AccountFirstPay", array("Channel" => $Channel, "PayYMD" => $YMD), $ret, array("AccountID" => 1));  | 
|     $firstPayAccountIDInfo = array();  | 
|     if (isset($ret)) {  | 
|         foreach ($ret as $firstPayInfo) {  | 
|             $AccountID = $firstPayInfo["AccountID"];  | 
|             $firstPayAccountIDInfo[$AccountID] = 1;  | 
|         }  | 
|     }  | 
|   | 
|     $ret = \DBOper\Aggregate("PayOrder", array(  | 
|         array(  | 
|             '$match' => array(  | 
|                 "Channel" => $Channel, "State" => 1,  | 
|                 "PayTime" => array('$gte' => $YMD . " 00:00:00", '$lte' => $YMD . " 23:59:59")  | 
|             ),  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => array('AccountID' => '$AccountID'),  | 
|                 'total' => array('$sum' => '$OrderAmount'),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     $DPU = 0;  | 
|     $DRPU = 0;  | 
|     $DRNPU = 0;  | 
|     if ($ret && isset($retInfo)) {  | 
|         foreach ($retInfo as $info) {  | 
|             $DPU += 1;  | 
|             $AccountID = $info["_id"]["AccountID"];  | 
|             $DRPU += $info["total"];  | 
|             if ($firstPayAccountIDInfo[$AccountID]) {  | 
|                 $DRNPU += $info["total"];  | 
|             }  | 
|         }  | 
|     }  | 
|     $DRPU = round($DRPU, 2);  | 
|     $DRNPU = round($DRNPU, 2);  | 
|     $DNPU = count($firstPayAccountIDInfo);  | 
|     \Logging\LogInfo(" 日新增充值用户数 DNPU:" . $DNPU);  | 
|     \Logging\LogInfo(" 日新增充值用户充值总额 DRNPU:" . $DRNPU);  | 
|     \Logging\LogInfo(" 日充值用户数 DPU:" . $DPU);  | 
|     \Logging\LogInfo(" 日充值用户数充值总额 DRPU:" . $DRPU);  | 
|   | 
|     return array(  | 
|         "Channel" => $Channel, "YMD" => $YMD,  | 
|         "DAU" => $DAU,  | 
|         "DNU" => $DNU,  | 
|         "DNPU" => $DNPU,  | 
|         "DRNPU" => $DRNPU,  | 
|         "DPU" => $DPU,  | 
|         "DRPU" => $DRPU,  | 
|     );  | 
| }  | 
|   | 
| /**检查并导出首登/首充每日报表 */  | 
| function CheckAndExportFirstKeepReport($Channel)  | 
| {  | 
|     $eventKey = "FirstKeepReportYMD_" . $Channel;  | 
|     if (!\DBOper\FindOne("ServerEvent", array("Key" => $eventKey), $ret, null, false)) {  | 
|         return;  | 
|     }  | 
|     $reportYMD = $ret["Value"] ? $ret["Value"] : ""; // 最后一次成功导出报表日期  | 
|   | 
|     $StartYMDTime = 0; // 需要导出的起始日期时间戳  | 
|     if ($reportYMD) {  | 
|         $StartYMDTime = strtotime("+1 day", strtotime($reportYMD)); // 从+1天开始导出  | 
|         \Logging\LogInfo("ExportFirstKeepReport Channel:" . $Channel . " reportYMD:" . $reportYMD . " StartYMDTime:" . date("Y-m-d", $StartYMDTime));  | 
|     } else {  | 
|         // 取出最早的首登日期  | 
|         if (!\DBOper\FindOneSort("AccountFirstLogin", array("Channel" => $Channel), $retInfo, array("CreateYMD" => 1), array("CreateYMD" => 1))) {  | 
|             return;  | 
|         }  | 
|         if (!isset($retInfo)) {  | 
|             \Logging\LogInfo("ExportFirstKeepReport AccountFirstLogin 还没有数据,不用导出! Channel:" . $Channel);  | 
|             return;  | 
|         }  | 
|         $StartYMDTime = strtotime($retInfo["CreateYMD"]);  | 
|         \Logging\LogInfo("ExportFirstKeepReport Channel:" . $Channel . " AccountFirstLogin StartYMDTime:" . date("Y-m-d", $StartYMDTime));  | 
|     }  | 
|     if (!$StartYMDTime) {  | 
|         return;  | 
|     }  | 
|   | 
|     $StartYMD = date("Y-m-d", $StartYMDTime);  | 
|     $EndYMDTime = strtotime("-1 day", strtotime(date("Y-m-d"))); // 只导出到昨天  | 
|     $diffSeconds = $EndYMDTime - $StartYMDTime;  | 
|     $diffDays = floor($diffSeconds / (3600 * 24)) + 1;  | 
|     if ($diffDays <= 0) {  | 
|         \Logging\LogInfo("【 " . $Channel . " 】不需要导出首登每日报表! StartYMD:" . $StartYMD);  | 
|         return;  | 
|     }  | 
|     $EndYMD = date("Y-m-d", $EndYMDTime);  | 
|     \Logging\LogInfo("===== 开始导出首登每日报表 【" . $Channel . "】 =====");  | 
|     \Logging\LogInfo("StartYMD:" . $StartYMD . " EndYMD:" . $EndYMD);  | 
|   | 
|     $fistLoginReportArray = array();  | 
|     $fistPayReportArray = array();  | 
|     while ($StartYMDTime <= $EndYMDTime && $diffDays >= 0) {  | 
|         $diffDays -= 1;  | 
|         $exportActiveYMD = date("Y-m-d", $StartYMDTime);  | 
|   | 
|         if (!StatFirstKeepReport($Channel, $exportActiveYMD, $fistLoginReportArray, $fistPayReportArray, $accountFirstLoginDateInfo, $accountFirstPayDateInfo)) {  | 
|             return;  | 
|         }  | 
|         $StartYMDTime = strtotime("+1 day", $StartYMDTime);  | 
|     }  | 
|     \Logging\LogInfo("fistLoginReportArray:" . print_r($fistLoginReportArray, true));  | 
|     \Logging\LogInfo("fistPayReportArray:" . print_r($fistPayReportArray, true));  | 
|   | 
|     // 生成插入数据  | 
|     $batchInsDatas = array();  | 
|     foreach ($fistLoginReportArray as $CreateYMD => $ymdArray) {  | 
|         foreach ($ymdArray as $ReportYMD => $statInfo) {  | 
|             $keepCount = $statInfo["keepCount"] ? $statInfo["keepCount"] : 0;  | 
|             $payTotal = $statInfo["payTotal"] ? $statInfo["payTotal"] : 0;  | 
|             $payCnt = $statInfo["payCnt"] ? $statInfo["payCnt"] : 0;  | 
|             $firstPayCnt = $statInfo["firstPayCnt"] ? $statInfo["firstPayCnt"] : 0;  | 
|             array_push($batchInsDatas, array(  | 
|                 "Channel" => $Channel,  | 
|                 "CreateYMD" => $CreateYMD,  | 
|                 "ReportYMD" => $ReportYMD,  | 
|                 "KeepCount" => $keepCount,  | 
|                 "PayTotal" => $payTotal,  | 
|                 "PayCnt" => $payCnt,  | 
|                 "FirstPayCnt" => $firstPayCnt,  | 
|             ));  | 
|         }  | 
|     }  | 
|   | 
|     if (count($batchInsDatas) > 0) {  | 
|         // 每次清除后重新插入  | 
|         \DBOper\Remove("AccountFirstLoginReport", array("Channel" => $Channel, "ReportYMD" => array('$gte' => $StartYMD)));  | 
|         if (!\DBOper\BatchInsert("AccountFirstLoginReport", $batchInsDatas)) {  | 
|             return;  | 
|         }  | 
|         \Logging\LogInfo("AccountFirstLoginReport 插入OK:" . count($batchInsDatas));  | 
|     }  | 
|   | 
|     // 生成插入数据  | 
|     $batchInsDatas = array();  | 
|     foreach ($fistPayReportArray as $FirstPayYMD => $ymdArray) {  | 
|         foreach ($ymdArray as $ReportYMD => $statInfo) {  | 
|             $keepCount = $statInfo["keepCount"] ? $statInfo["keepCount"] : 0;  | 
|             array_push($batchInsDatas, array(  | 
|                 "Channel" => $Channel,  | 
|                 "FirstPayYMD" => $FirstPayYMD,  | 
|                 "ReportYMD" => $ReportYMD,  | 
|                 "KeepCount" => $keepCount,  | 
|             ));  | 
|         }  | 
|     }  | 
|   | 
|     if (count($batchInsDatas) > 0) {  | 
|         // 每次清除后重新插入  | 
|         \DBOper\Remove("AccountFirstPayReport", array("Channel" => $Channel, "ReportYMD" => array('$gte' => $StartYMD)));  | 
|         if (!\DBOper\BatchInsert("AccountFirstPayReport", $batchInsDatas)) {  | 
|             return;  | 
|         }  | 
|         \Logging\LogInfo("AccountFirstPayReport 插入OK:" . count($batchInsDatas));  | 
|     }  | 
|   | 
|     // 全部处理完毕才更新  | 
|     \DBOper\Update("ServerEvent", array("Key" => $eventKey), array("Value" => $EndYMD), false, true);  | 
|     \Logging\LogInfo("==============================================");  | 
| }  | 
|   | 
| /**  | 
|  * 统计首登相关留存日期报表,包含充值(用于ltv计算)  | 
|  * @param string $Channel  | 
|  * @param string $YMD 要统计的报表日期yyyy-MM-dd  | 
|  * @param array $fistLoginReportArray 统计首登报表结果 {首登日期:{统计日期:{keepCount:x, payTotal:x, payCnt:x, firstPayCnt:x}} ...}}  | 
|  * @param array $fistPayReportArray 统计首充报表结果 {首充日期:{统计日期:{keepCount:x}} ...}}  | 
|  * @param array $accountFirstLoginDateInfo 账号首登日期信息 {accountID:firstLoginYMD, ...}  | 
|  * @param array $accountFirstPayDateInfo 账号首充日期信息 {accountID:firstPayYMD, ...}  | 
|  */  | 
| function StatFirstKeepReport($Channel, $YMD, &$fistLoginReportArray, &$fistPayReportArray, &$accountFirstLoginDateInfo = null, &$accountFirstPayDateInfo = null)  | 
| {  | 
|     \Logging\LogInfo("=== 统计: " . $YMD);  | 
|     if (!isset($fistLoginReportArray)) {  | 
|         $fistLoginReportArray = array();  | 
|     }  | 
|     if (!isset($fistPayReportArray)) {  | 
|         $fistPayReportArray = array();  | 
|     }  | 
|     if (!isset($accountFirstLoginDateInfo)) {  | 
|         $accountFirstLoginDateInfo = array();  | 
|     }  | 
|     if (!isset($accountFirstPayDateInfo)) {  | 
|         $accountFirstPayDateInfo = array();  | 
|     }  | 
|     if (  | 
|         !\DBOper\Find(  | 
|             "AccountDayActive",  | 
|             array("Channel" => $Channel, "ActiveYMD" => $YMD),  | 
|             $activeRetArray,  | 
|             array("AccountID" => 1)  | 
|         ) || !isset($activeRetArray)  | 
|     ) {  | 
|         return;  | 
|     }  | 
|   | 
|     $dayActiveAccIDDict = array(); // 统计日期活跃账号充值额度 {accountID:充值总额, ...}  | 
|     $queryFirstLoginAccIDList = array(); // 需要查询首登日期的账号列表 [accountID, ..]  | 
|     $queryFirstPayAccIDList = array(); // 需要查询首充日期的账号列表 [accountID, ..]  | 
|     foreach ($activeRetArray as $activeInfo) {  | 
|         $AccountID = $activeInfo["AccountID"];  | 
|   | 
|         $dayActiveAccIDDict[$AccountID] = 0;  | 
|   | 
|         if (!isset($accountFirstLoginDateInfo[$AccountID])) {  | 
|             array_push($queryFirstLoginAccIDList, $AccountID);  | 
|         }  | 
|         if (!isset($accountFirstPayDateInfo[$AccountID])) {  | 
|             array_push($queryFirstPayAccIDList, $AccountID);  | 
|         }  | 
|     }  | 
|   | 
|     if (count($queryFirstLoginAccIDList) > 0) {  | 
|         if (  | 
|             !\DBOper\Find(  | 
|                 "AccountFirstLogin",  | 
|                 array("Channel" => $Channel, "AccountID" => array('$in' => $queryFirstLoginAccIDList)),  | 
|                 $accountRetArray,  | 
|                 array("AccountID" => 1, "CreateYMD" => 1)  | 
|             ) || !isset($accountRetArray)  | 
|         ) {  | 
|             return;  | 
|         }  | 
|         foreach ($accountRetArray as $accountInfo) {  | 
|             $accountFirstLoginDateInfo[$accountInfo["AccountID"]] = $accountInfo["CreateYMD"];  | 
|         }  | 
|     }  | 
|     if (count($queryFirstPayAccIDList) > 0) {  | 
|         if (  | 
|             !\DBOper\Find(  | 
|                 "AccountFirstPay",  | 
|                 array("Channel" => $Channel, "AccountID" => array('$in' => $queryFirstPayAccIDList)),  | 
|                 $accountPayRetArray,  | 
|                 array("AccountID" => 1, "PayYMD" => 1)  | 
|             ) || !isset($accountPayRetArray)  | 
|         ) {  | 
|             return;  | 
|         }  | 
|   | 
|         foreach ($accountPayRetArray as $accountInfo) {  | 
|             $accountFirstPayDateInfo[$accountInfo["AccountID"]] = $accountInfo["PayYMD"];  | 
|         }  | 
|     }  | 
|   | 
|     // 今日首付账号  | 
|     if (  | 
|         !\DBOper\Find("AccountFirstPay", array("Channel" => $Channel, "PayYMD" => $YMD), $firstPayRetArray, array("AccountID" => 1))  | 
|         || !isset($firstPayRetArray)  | 
|     ) {  | 
|         return;  | 
|     }  | 
|     $accountFirstPayDict = array(); // 统计日期首付账号  | 
|     foreach ($firstPayRetArray as $firstPayInfo) {  | 
|         $accountFirstPayDict[$firstPayInfo["AccountID"]] = 1;  | 
|     }  | 
|   | 
|     $ret = \DBOper\Aggregate("PayOrder", array(  | 
|         array(  | 
|             '$match' => array(  | 
|                 "Channel" => $Channel, "State" => 1, "PayTime" => array('$gte' => $YMD . " 00:00:00", '$lte' => $YMD . " 23:59:59")  | 
|             ),  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => array('AccountID' => '$AccountID'),  | 
|                 'total' => array('$sum' => '$OrderAmount'),  | 
|             ),  | 
|         ),  | 
|     ), $retInfo);  | 
|     if (!$ret || !isset($retInfo)) {  | 
|         return;  | 
|     }  | 
|     foreach ($retInfo as $info) {  | 
|         $AccountID = $info["_id"]["AccountID"];  | 
|         if (isset($dayActiveAccIDDict[$AccountID])) {  | 
|             $dayActiveAccIDDict[$AccountID] = floatval($info["total"]);  | 
|         }  | 
|     }  | 
|   | 
|     // 汇总信息  | 
|     foreach ($dayActiveAccIDDict as $AccountID => $payTotal) {  | 
|         // 首登  | 
|         $FirstLoginYMD = $accountFirstLoginDateInfo[$AccountID];  | 
|         if ($FirstLoginYMD) {  | 
|             if (!isset($fistLoginReportArray[$FirstLoginYMD])) {  | 
|                 $fistLoginReportArray[$FirstLoginYMD] = array();  | 
|             }  | 
|             $statYMDInfo = $fistLoginReportArray[$FirstLoginYMD];  | 
|             if (!isset($statYMDInfo[$YMD])) {  | 
|                 $statYMDInfo[$YMD] = array("keepCount" => 0, "payTotal" => 0, "payCnt" => 0, "firstPayCnt" => 0);  | 
|             }  | 
|             $statInfo = $statYMDInfo[$YMD];  | 
|             $statInfo["keepCount"] = ($statInfo["keepCount"] ? $statInfo["keepCount"] : 0) + 1;  | 
|             $statInfo["payTotal"] = ($statInfo["payTotal"] ? $statInfo["payTotal"] : 0) + $payTotal;  | 
|             if ($payTotal > 0) {  | 
|                 $statInfo["payCnt"] = ($statInfo["payCnt"] ? $statInfo["payCnt"] : 0) + 1;  | 
|             }  | 
|   | 
|             if ($accountFirstPayDict[$AccountID]) {  | 
|                 $statInfo["firstPayCnt"] = ($statInfo["firstPayCnt"] ? $statInfo["firstPayCnt"] : 0) + 1;  | 
|             }  | 
|   | 
|             $statYMDInfo[$YMD] = $statInfo;  | 
|             $fistLoginReportArray[$FirstLoginYMD] = $statYMDInfo;  | 
|         }  | 
|   | 
|         // 首充  | 
|         $FirstPayYMD = $accountFirstPayDateInfo[$AccountID];  | 
|         if ($FirstPayYMD) {  | 
|             if (!isset($fistPayReportArray[$FirstPayYMD])) {  | 
|                 $fistPayReportArray[$FirstPayYMD] = array();  | 
|             }  | 
|             $statYMDInfo = $fistPayReportArray[$FirstPayYMD];  | 
|             if (!isset($statYMDInfo[$YMD])) {  | 
|                 $statYMDInfo[$YMD] = array();  | 
|             }  | 
|             $statInfo = $statYMDInfo[$YMD];  | 
|             $statInfo["keepCount"] = ($statInfo["keepCount"] ? $statInfo["keepCount"] : 0) + 1;  | 
|   | 
|             $statYMDInfo[$YMD] = $statInfo;  | 
|             $fistPayReportArray[$FirstPayYMD] = $statYMDInfo;  | 
|         }  | 
|     }  | 
|     \Logging\LogInfo("统计每日首登OK " . $YMD);  | 
|     return true;  | 
| }  | 
|   | 
| /**  | 
|  * 获取每日报表  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @param boolean $returnDateKey 是否以日期为字典key格式返回  | 
|  * @return array [{k:v, ...}, ...] 或 {dateYMD:{k:v, ...}, ...}  | 
|  */  | 
| function GetDailyReport($Channel, $fromYMD, $toYMD, $returnDateKey = False)  | 
| {  | 
|     CheckAndExportDailyReport($Channel); // 每次获取检查导出  | 
|     $find = array("Channel" => $Channel, "YMD" => array('$gte' => $fromYMD, '$lte' => $toYMD));  | 
|     \DBOper\Find("DailyReport", $find, $retArray);  | 
|     if (!isset($retArray)) {  | 
|         $retArray = array();  | 
|     }  | 
|     $curYMD = date("Y-m-d");  | 
|     if ($toYMD >= $curYMD) {  | 
|         // 包含当日,实时统计  | 
|         array_push($retArray, StatDailyReport($Channel, $curYMD));  | 
|     }  | 
|     if ($returnDateKey) {  | 
|         $retDict = array();  | 
|         foreach ($retArray as $repData) {  | 
|             $retDict[$repData["YMD"]] = $repData;  | 
|         }  | 
|         return $retDict;  | 
|     }  | 
|     return $retArray;  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内新用户数总数  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @return int 总数  | 
|  */  | 
| function QueryNewUserCount($Channel, $fromYMD = "", $toYMD = "")  | 
| {  | 
|     $find = array("Channel" => $Channel);  | 
|     $ymdCond = array();  | 
|     if ($fromYMD) {  | 
|         $ymdCond['$gte'] = $fromYMD;  | 
|     }  | 
|     if ($toYMD) {  | 
|         $ymdCond['$lte'] = $toYMD;  | 
|     }  | 
|     if (count($ymdCond)) {  | 
|         $find["CreateYMD"] = $ymdCond;  | 
|     }  | 
|     $count = \DBOper\Count("AccountFirstLogin", $find);  | 
|     return $count;  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内每日新用户数  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @param array $dateCountInfo {date:count, ...}  | 
|  * @return int 总数  | 
|  */  | 
| function QueryNewUserCountByDate($Channel, $fromYMD, $toYMD, &$dateCountInfo)  | 
| {  | 
|     $count = 0;  | 
|     $find = array("Channel" => $Channel, "CreateYMD" => array('$gte' => $fromYMD, '$lte' => $toYMD));  | 
|     $ret = \DBOper\Aggregate("AccountFirstLogin", array(  | 
|         array(  | 
|             '$match' => $find,  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => '$CreateYMD',  | 
|                 'count' => array('$sum' => 1),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     if ($ret && isset($retInfo)) {  | 
|         foreach ($retInfo as $info) {  | 
|             $count += $info["count"];  | 
|             $dateCountInfo[$info["_id"]] = $info["count"];  | 
|         }  | 
|         ksort($dateCountInfo);  | 
|     }  | 
|     return $count;  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内新付费用户数总数  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @return int 总数  | 
|  */  | 
| function QueryNewPayUserCount($Channel, $fromYMD = "", $toYMD = "")  | 
| {  | 
|     $find = array("Channel" => $Channel);  | 
|     $ymdCond = array();  | 
|     if ($fromYMD) {  | 
|         $ymdCond['$gte'] = $fromYMD;  | 
|     }  | 
|     if ($toYMD) {  | 
|         $ymdCond['$lte'] = $toYMD;  | 
|     }  | 
|     if (count($ymdCond)) {  | 
|         $find["PayYMD"] = $ymdCond;  | 
|     }  | 
|     $count = \DBOper\Count("AccountFirstPay", $find);  | 
|     return $count;  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内每日新付费用户数  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @param array $dateCountInfo {date:count, ...}  | 
|  * @return int 总数  | 
|  */  | 
| function QueryNewPayUserCountByDate($Channel, $fromYMD, $toYMD, &$dateCountInfo)  | 
| {  | 
|     $count = 0;  | 
|     $find = array("Channel" => $Channel, "PayYMD" => array('$gte' => $fromYMD, '$lte' => $toYMD));  | 
|     $ret = \DBOper\Aggregate("AccountFirstPay", array(  | 
|         array(  | 
|             '$match' => $find,  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => '$PayYMD',  | 
|                 'count' => array('$sum' => 1),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     if ($ret && isset($retInfo)) {  | 
|         foreach ($retInfo as $info) {  | 
|             $count += $info["count"];  | 
|             $dateCountInfo[$info["_id"]] = $info["count"];  | 
|         }  | 
|         ksort($dateCountInfo);  | 
|     }  | 
|     return $count;  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内活跃用户数总数  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @return int 总数  | 
|  */  | 
| function QueryActiveUserCount($Channel, $fromYMD, $toYMD)  | 
| {  | 
|     $count = 0;  | 
|     $find = array("Channel" => $Channel, "ActiveYMD" => array('$gte' => $fromYMD, '$lte' => $toYMD));  | 
|     $ret = \DBOper\Aggregate("AccountDayActive", array(  | 
|         array(  | 
|             '$match' => $find,  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => '$AccountID', // 按账号去重分组  | 
|                 'count' => array('$sum' => 1),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     if ($ret && isset($retInfo)) {  | 
|         $count = count($retInfo);  | 
|     }  | 
|     return $count;  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内每日活跃用户数  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @param array $dateCountInfo {date:count, ...}  | 
|  * @return int 总数(未去重账号)  | 
|  */  | 
| function QueryActiveUserCountByDate($Channel, $fromYMD, $toYMD, &$dateCountInfo)  | 
| {  | 
|     $count = 0;  | 
|     $find = array("Channel" => $Channel, "ActiveYMD" => array('$gte' => $fromYMD, '$lte' => $toYMD));  | 
|     $ret = \DBOper\Aggregate("AccountDayActive", array(  | 
|         array(  | 
|             '$match' => $find,  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => '$ActiveYMD',  | 
|                 'count' => array('$sum' => 1),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     if ($ret && isset($retInfo)) {  | 
|         foreach ($retInfo as $info) {  | 
|             $count += $info["count"];  | 
|             $dateCountInfo[$info["_id"]] = $info["count"];  | 
|         }  | 
|         ksort($dateCountInfo);  | 
|     }  | 
|     return $count;  | 
| }  | 
|   | 
|   | 
| /**  | 
|  * 查询日期范围内充值用户及付费总额  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @return array (总人数, 总额度)  | 
|  */  | 
| function QueryPayUserCountAndTotal($Channel, $fromYMD, $toYMD)  | 
| {  | 
|     $count = 0;  | 
|     $total = 0;  | 
|     $find = array("Channel" => $Channel, "State" => 1);  | 
|     $ymdCond = array();  | 
|     if ($fromYMD) {  | 
|         $ymdCond['$gte'] = $fromYMD . " 00:00:00";  | 
|     }  | 
|     if ($toYMD) {  | 
|         $ymdCond['$lte'] = $toYMD . " 23:59:59";  | 
|     }  | 
|     if (count($ymdCond)) {  | 
|         $find["PayTime"] = $ymdCond;  | 
|     }  | 
|     $ret = \DBOper\Aggregate("PayOrder", array(  | 
|         array(  | 
|             '$match' => $find,  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => '$AccountID', // 按账号去重分组  | 
|                 'total' => array('$sum' =>  '$OrderAmount'),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     if ($ret && isset($retInfo)) {  | 
|         foreach ($retInfo as $info) {  | 
|             $count += 1;  | 
|             $total += $info["total"];  | 
|         }  | 
|     }  | 
|     return array($count, $total);  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内充值用户总数  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @return int 总数  | 
|  */  | 
| function QueryPayUserCount($Channel, $fromYMD, $toYMD)  | 
| {  | 
|     $count = 0;  | 
|     $find = array("Channel" => $Channel, "State" => 1);  | 
|     $ymdCond = array();  | 
|     if ($fromYMD) {  | 
|         $ymdCond['$gte'] = $fromYMD . " 00:00:00";  | 
|     }  | 
|     if ($toYMD) {  | 
|         $ymdCond['$lte'] = $toYMD . " 23:59:59";  | 
|     }  | 
|     if (count($ymdCond)) {  | 
|         $find["PayTime"] = $ymdCond;  | 
|     }  | 
|     $ret = \DBOper\Aggregate("PayOrder", array(  | 
|         array(  | 
|             '$match' => $find,  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => '$AccountID', // 按账号去重分组  | 
|                 'count' => array('$sum' => 1),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     if ($ret && isset($retInfo)) {  | 
|         $count = count($retInfo);  | 
|     }  | 
|     return $count;  | 
| }  | 
|   | 
| /**  | 
|  * 查询日期范围内累计付费  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @return int 总付费  | 
|  */  | 
| function QueryPayTotal($Channel, $fromYMD = "", $toYMD = "")  | 
| {  | 
|     $total = 0;  | 
|     $find = array("Channel" => $Channel, "State" => 1);  | 
|     $ymdCond = array();  | 
|     if ($fromYMD) {  | 
|         $ymdCond['$gte'] = $fromYMD . " 00:00:00";  | 
|     }  | 
|     if ($toYMD) {  | 
|         $ymdCond['$lte'] = $toYMD . " 23:59:59";  | 
|     }  | 
|     if (count($ymdCond)) {  | 
|         $find["PayTime"] = $ymdCond;  | 
|     }  | 
|     $ret = \DBOper\Aggregate("PayOrder", array(  | 
|         array(  | 
|             '$match' => $find,  | 
|         ),  | 
|         array(  | 
|             '$group' => array(  | 
|                 '_id' => null,  | 
|                 'total' => array('$sum' =>  '$OrderAmount'),  | 
|             ),  | 
|         )  | 
|     ), $retInfo);  | 
|     if ($ret && isset($retInfo) && count($retInfo) > 0) {  | 
|         $total = $retInfo[0]["total"];  | 
|         // foreach ($retInfo as $info) {  | 
|         //     $total += $info["total"];  | 
|         // }  | 
|     }  | 
|     return round($total, 2);  | 
| }  | 
|   | 
| /**  | 
|  * 获取首登及首充用户相关报表  | 
|  * @param string $Channel  | 
|  * @param string $fromYMD 起始日期yyyy-MM-dd  | 
|  * @param string $toYMD 到日期yyyy-MM-dd  | 
|  * @param array &$fistLoginReportArray {首登日期:{统计日期:{keepCount:x, payTotal:x, payCnt:x, firstPayCnt:x}} ...}}  | 
|  * @param array &$fistPayReportArray {首充日期:{统计日期:{keepCount:x}} ...}}  | 
|  */  | 
| function GetAccountFirstLoginPayReport($Channel, $fromYMD, $toYMD, &$fistLoginReportArray, &$fistPayReportArray)  | 
| {  | 
|     CheckAndExportFirstKeepReport($Channel); // 每次获取检查导出  | 
|     $find = array("Channel" => $Channel, "CreateYMD" => array('$gte' => $fromYMD, '$lte' => $toYMD));  | 
|     \DBOper\Find("AccountFirstLoginReport", $find, $newUserRetArray);  | 
|     if (!isset($newUserRetArray)) {  | 
|         $newUserRetArray = array();  | 
|     }  | 
|   | 
|     $find = array("Channel" => $Channel, "FirstPayYMD" => array('$gte' => $fromYMD, '$lte' => $toYMD));  | 
|     \DBOper\Find("AccountFirstPayReport", $find, $newPayUserRetArray, array("FirstPayYMD" => 1, "ReportYMD" => 1, "KeepCount" => 1));  | 
|     if (!isset($newPayUserRetArray)) {  | 
|         $newPayUserRetArray = array();  | 
|     }  | 
|   | 
|     $curYMD = date("Y-m-d");  | 
|     if ($toYMD >= $curYMD) {  | 
|         // 包含当日,实时统计  | 
|         StatFirstKeepReport($Channel, $curYMD, $fistLoginReportArray, $fistPayReportArray);  | 
|     }  | 
|   | 
|     foreach ($newUserRetArray as $info) {  | 
|         $FirstLoginYMD = $info["CreateYMD"];  | 
|         $ReportYMD = $info["ReportYMD"];  | 
|         if (!isset($fistLoginReportArray[$FirstLoginYMD])) {  | 
|             $fistLoginReportArray[$FirstLoginYMD] = array();  | 
|         }  | 
|         $statYMDInfo = $fistLoginReportArray[$FirstLoginYMD];  | 
|         $statYMDInfo[$ReportYMD] = array(  | 
|             "keepCount" => $info["KeepCount"], "payTotal" => $info["PayTotal"],  | 
|             "payCnt" => $info["PayCnt"], "firstPayCnt" => $info["FirstPayCnt"]  | 
|         );  | 
|         $fistLoginReportArray[$FirstLoginYMD] = $statYMDInfo;  | 
|     }  | 
|     ksort($fistLoginReportArray);  | 
|   | 
|     foreach ($newPayUserRetArray as $info) {  | 
|         $FirstPayYMD = $info["FirstPayYMD"];  | 
|         $ReportYMD = $info["ReportYMD"];  | 
|         if (!isset($fistPayReportArray[$FirstPayYMD])) {  | 
|             $fistPayReportArray[$FirstPayYMD] = array();  | 
|         }  | 
|         $statYMDInfo = $fistPayReportArray[$FirstPayYMD];  | 
|         $statYMDInfo[$ReportYMD] = array("keepCount" => $info["KeepCount"]);  | 
|         $fistPayReportArray[$FirstPayYMD] = $statYMDInfo;  | 
|     }  | 
|     ksort($fistPayReportArray);  | 
|     return;  | 
| }  | 
|   | 
| // function test()  | 
| // {  | 
| //     echo "run test" . "<br/>";  | 
| //     \Logging\CreateLogging("test.report.php");  | 
| //     $AllChannel = \CommFunc\GetAllChannel();  | 
| //     for ($i = 0; $i < count($AllChannel); $i++) {  | 
| //         $Channel = $AllChannel[$i];  | 
| //         echo "run Channel" . $Channel . "<br/>";  | 
| //         CheckAndExportDailyReport($Channel);  | 
| //         CheckAndExportFirstKeepReport($Channel);  | 
| //     }  | 
| //     echo "run test end" . "<br/>";  | 
| // }  | 
| // test(); |