Remain.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <?php
  2. /**
  3. * 留存相关
  4. */
  5. defined('IN_WEB') or die('Include Error!');
  6. include_once dirname(__FILE__) . "/Base.php";
  7. class Remain extends Base
  8. {
  9. private $_sidList = [];
  10. /**
  11. * 留存首页
  12. */
  13. public function index($param)
  14. {
  15. $stime = oo::functions()->uint($param['stime']);
  16. $etime = oo::functions()->uint($param['etime']);
  17. $isCache = oo::functions()->uint($param['isCache']);
  18. $sidList = json_decode($param['sidList'], 1);
  19. if(empty($sidList)) {
  20. return json_encode([]);
  21. }
  22. $this->_sidList = $sidList;
  23. $cacheKey = okeys::keydata('REMAIN');
  24. $isAllSid = $this->isAllSid($sidList);
  25. if($isAllSid) {
  26. if($isCache == 1) {
  27. $keydataInfo = oo::commonOprRedis('common')->get($cacheKey);
  28. if(!empty($keydataInfo)){
  29. return $keydataInfo;
  30. }
  31. }
  32. }
  33. $daysList = $this->getDays($stime, $etime, 2);
  34. $data['daylist'] = $daysList;
  35. $day1Remain = $day3Remain = $day7Remain = $day1ActRemain = $day3ActRemain = $day7ActRemain = array();
  36. foreach ($daysList as $day) {//此处已经减少了一天
  37. $days1ago = $day;
  38. $days2ago = date('Ymd', strtotime($day.'-1 day'));
  39. $days3age = date('Ymd', strtotime($day.'-3 days'));
  40. $days8age = date('Ymd', strtotime($day.'-7 days'));
  41. $days15age = date('Ymd', strtotime($day.'-15 days'));
  42. $days30age = date('Ymd', strtotime($day.'-30 days'));//30天没数据,先按29天的算
  43. // $days30age = date('Ymd', strtotime($day.'-20 days'));
  44. $days60age = date('Ymd', strtotime($day.'-60 days'));
  45. ////次日新增留存 比如今天29号 就计算28号的次日留存 那么新增玩家从27号算,
  46. $yesterdayPlayer = $this->getAllPlayer($days1ago, 2);//登陆玩家
  47. $last2daysPlayer = $this->getAllPlayer($days2ago, 1);//新增玩家
  48. $intersect1dayPlay = array_intersect($yesterdayPlayer, $last2daysPlayer);//交集玩家
  49. $tempDay1Remain = empty(count($last2daysPlayer)) ? 0 : count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率
  50. $data['day1Remain'][] = round($tempDay1Remain, 4)*100;//次日留存率
  51. //$data['day1Remain'][] = count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率
  52. //3日新增留存
  53. $last3daysPlayer = $this->getAllPlayer($days3age, 1);//新增玩家
  54. $intersect3dayPlay = array_intersect($yesterdayPlayer, $last3daysPlayer);//交集玩家
  55. //$data['day3Remain'][] = count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
  56. $tday3Remain = empty(count($last3daysPlayer)) ? 0 : count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
  57. $data['day3Remain'][] = round($tday3Remain, 4)*100;//3日留存率
  58. //7日新增留存
  59. $last8daysPlayer = $this->getAllPlayer($days8age, 1);//新增玩家
  60. $intersect8dayPlay = array_intersect($yesterdayPlayer, $last8daysPlayer);//交集玩家
  61. $data['day7Remain'][] = empty(count($last8daysPlayer)) ? 0 : round( count($intersect8dayPlay) / count($last8daysPlayer), 4 )*100;//3日留存率
  62. //15日新增留存
  63. $last15daysPlayer = $this->getAllPlayer($days15age, 1);//新增玩家
  64. $intersect15dayPlay = array_intersect($yesterdayPlayer, $last15daysPlayer);//交集玩家
  65. $data['day15Remain'][] = empty(count($last15daysPlayer)) ? 0 : round( count($intersect15dayPlay) / count($last15daysPlayer), 4 )*100;//15日留存率
  66. //30日新增留存
  67. $last30daysPlay = $this->getAllPlayer($days30age, 1);//30天新增玩家
  68. $intersect30dayPlay = array_intersect($yesterdayPlayer, $last30daysPlay); //交集玩家
  69. // oo::logs()->debug3(array('$last30daysPlay' => $last30daysPlay, '$intersect30dayPlay' => $intersect30dayPlay), 'Keydata.php');
  70. $data['day30Remain'][] = empty(count($last30daysPlay)) ? 0 : round(count($intersect30dayPlay) / count($last30daysPlay), 4) * 100;//30日留存率
  71. //60日新增留存
  72. $last60daysPlayer = $this->getAllPlayer($days60age, 1);//新增玩家
  73. $intersect60dayPlay = array_intersect($yesterdayPlayer, $last60daysPlayer);//交集玩家
  74. $data['day60Remain'][] = empty(count($last60daysPlayer)) ? 0 : round( count($intersect60dayPlay) / count($last60daysPlayer), 4 )*100;//60日留存率
  75. //次日活跃留存
  76. $yesterdayLoginPlayer = $this->getAllPlayer($days1ago, 2);//登陆玩家
  77. $last2daysLoginPlayer = $this->getAllPlayer($days2ago, 2);//登陆玩家
  78. $intersect1dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last2daysLoginPlayer);//交集玩家
  79. $data['day1ActRemain'][] = empty(count($last2daysLoginPlayer)) ? 0 : round( count($intersect1dayLoginPlay) / count($last2daysLoginPlayer), 4 )*100;//次日留存率
  80. //3日活跃留存
  81. $last3daysLoginPlayer = $this->getAllPlayer($days3age, 2);//登陆玩家
  82. $intersect3dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last3daysLoginPlayer);//交集玩家
  83. $data['day3ActRemain'][] = empty(count($last3daysLoginPlayer)) ? 0 : round(count( $intersect3dayLoginPlay) / count($last3daysLoginPlayer), 4 )*100;//3日留存率
  84. //7日活跃留存
  85. $last8daysLoginPlayer = $this->getAllPlayer($days8age, 2);//登陆玩家
  86. $intersect8dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last8daysLoginPlayer);//交集玩家
  87. $data['day7ActRemain'][] = empty(count($last8daysLoginPlayer)) ? 0 : round( count($intersect8dayLoginPlay) / count($last8daysLoginPlayer), 4 )*100;//3日留存率
  88. //30日活跃留存
  89. $last30daysLoginPlayer = $this->getAllPlayer($days30age, 2);//近30天登录的玩家
  90. $intersect30daysLoginPlayer = array_intersect($yesterdayLoginPlayer, $last30daysLoginPlayer);//30天玩家与昨天玩家交集
  91. $data['day30ActRemain'][] = empty(count($last30daysLoginPlayer)) ? 0 : round( count($intersect30daysLoginPlayer) / count($last30daysLoginPlayer), 4) * 100; //30天留存率
  92. }
  93. $ret = json_encode($data);
  94. if($isAllSid) {
  95. if($isCache == 1) {
  96. oo::commonOprRedis('common')->set($cacheKey, $ret);
  97. oo::commonOprRedis('common')->expireAt($cacheKey, strtotime('23:59:59'));
  98. }
  99. }
  100. return $ret;
  101. }
  102. /**
  103. * 留存首页
  104. */
  105. public function tableIndex($param)
  106. {
  107. $stime = oo::functions()->uint($param['stime']);
  108. $etime = oo::functions()->uint($param['etime']);
  109. $page = oo::functions()->uint($param['page']);//起始页数
  110. $limit = oo::functions()->uint($param['limit']);//每页数量
  111. $table = otable::remainStatistics();
  112. $where = '1 = 1 ';
  113. if(!empty($stime)){
  114. $sdate = date('Ymd', $stime);
  115. $where .= " AND date >= {$sdate} ";
  116. }
  117. if(!empty($etime)){
  118. $edate = date('Ymd', $etime);
  119. $where .= " AND date <= {$edate} ";
  120. }
  121. $totalSql = "SELECT COUNT(*) AS total FROM {$table} WHERE $where ";
  122. $total = oo::commonOprDb('common')->getOne($totalSql, MYSQLI_ASSOC);
  123. $data['total'] = $total['total'];
  124. $sql = " SELECT * FROM {$table} WHERE {$where} ORDER BY date DESC LIMIT {$page}, {$limit}";
  125. // oo::logs()->debug3('sql:'.$sql);
  126. $data['list'] = oo::commonOprDb('common')->getAll($sql, 1);
  127. return json_encode($data);
  128. }
  129. /**
  130. * 设备留存首页
  131. */
  132. public function device($param)
  133. {
  134. $stime = oo::functions()->uint($param['stime']);
  135. $etime = oo::functions()->uint($param['etime']);
  136. $isCache = oo::functions()->uint($param['isCache']);
  137. $cacheKey = okeys::keydata('REMAINDEVICE');
  138. if($isCache == 1) {
  139. $keydataInfo = oo::commonOprRedis('common')->get($cacheKey);
  140. if(!empty($keydataInfo)){
  141. return $keydataInfo;
  142. }
  143. }
  144. $daysList = $this->getDays($stime, $etime, 2);
  145. $data['daylist'] = $daysList;
  146. $day1Remain = $day3Remain = $day7Remain = $day1ActRemain = $day3ActRemain = $day7ActRemain = array();
  147. foreach ($daysList as $day) {//此处已经减少了一天
  148. $days1ago = $day;
  149. $days2ago = date('Ymd', strtotime($day.'-1 day'));
  150. $days3age = date('Ymd', strtotime($day.'-3 days'));
  151. $days8age = date('Ymd', strtotime($day.'-7 days'));
  152. $days30age = date('Ymd', strtotime($day.'-30 days'));//30天没数据,先按29天的算
  153. // $days30age = date('Ymd', strtotime($day.'-20 days'));
  154. ////次日新增留存 比如今天29号 就计算28号的次日留存 那么新增玩家从27号算,
  155. $yesterdayPlayer = $this->getAllDevicePlayer($days1ago, 1);//登陆玩家
  156. $last2daysPlayer = $this->getAllDevicePlayer($days2ago, 2);//新增玩家
  157. $intersect1dayPlay = array_intersect($yesterdayPlayer, $last2daysPlayer);//交集玩家
  158. $tempDay1Remain = empty(count($last2daysPlayer)) ? 0 : count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率
  159. $data['day1Remain'][] = round($tempDay1Remain, 4)*100;//次日留存率
  160. //$data['day1Remain'][] = count($intersect1dayPlay) / count($last2daysPlayer);//次日留存率
  161. //3日新增留存
  162. $last3daysPlayer = $this->getAllDevicePlayer($days3age, 2);//新增玩家
  163. $intersect3dayPlay = array_intersect($yesterdayPlayer, $last3daysPlayer);//交集玩家
  164. //$data['day3Remain'][] = count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
  165. $tday3Remain = empty(count($last3daysPlayer)) ? 0 : count($intersect3dayPlay) / count($last3daysPlayer);//3日留存率
  166. $data['day3Remain'][] = round($tday3Remain, 4)*100;//3日留存率
  167. //7日新增留存
  168. $last8daysPlayer = $this->getAllDevicePlayer($days8age, 2);//新增玩家
  169. $intersect8dayPlay = array_intersect($yesterdayPlayer, $last8daysPlayer);//交集玩家
  170. $data['day7Remain'][] = empty(count($last8daysPlayer)) ? 0 : round( count($intersect8dayPlay) / count($last8daysPlayer), 4 )*100;//3日留存率
  171. //30日新增留存
  172. $last30daysPlay = $this->getAllDevicePlayer($days30age, 2);//30天新增玩家
  173. $intersect30dayPlay = array_intersect($yesterdayPlayer, $last30daysPlay); //交集玩家
  174. // oo::logs()->debug3(array('$last30daysPlay' => $last30daysPlay, '$intersect30dayPlay' => $intersect30dayPlay), 'Keydata.php');
  175. $data['day30Remain'][] = empty(count($last30daysPlay)) ? 0 : round(count($intersect30dayPlay) / count($last30daysPlay), 4) * 100;//30日留存率
  176. //次日活跃留存
  177. $yesterdayLoginPlayer = $this->getAllDevicePlayer($days1ago, 1);//登陆玩家
  178. $last2daysLoginPlayer = $this->getAllDevicePlayer($days2ago, 1);//登陆玩家
  179. $intersect1dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last2daysLoginPlayer);//交集玩家
  180. $data['day1ActRemain'][] = empty(count($last2daysLoginPlayer)) ? 0 : round( count($intersect1dayLoginPlay) / count($last2daysLoginPlayer), 4 )*100;//次日留存率
  181. //3日活跃留存
  182. $last3daysLoginPlayer = $this->getAllDevicePlayer($days3age, 1);//登陆玩家
  183. $intersect3dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last3daysLoginPlayer);//交集玩家
  184. $data['day3ActRemain'][] = empty(count($last3daysLoginPlayer)) ? 0 : round(count( $intersect3dayLoginPlay) / count($last3daysLoginPlayer), 4 )*100;//3日留存率
  185. //7日活跃留存
  186. $last8daysLoginPlayer = $this->getAllDevicePlayer($days8age, 1);//登陆玩家
  187. $intersect8dayLoginPlay = array_intersect($yesterdayLoginPlayer, $last8daysLoginPlayer);//交集玩家
  188. $data['day7ActRemain'][] = empty(count($last8daysLoginPlayer)) ? 0 : round( count($intersect8dayLoginPlay) / count($last8daysLoginPlayer), 4 )*100;//3日留存率
  189. //30日活跃留存
  190. $last30daysLoginPlayer = $this->getAllDevicePlayer($days30age, 1);//近30天登录的玩家
  191. $intersect30daysLoginPlayer = array_intersect($yesterdayLoginPlayer, $last30daysLoginPlayer);//30天玩家与昨天玩家交集
  192. $data['day30ActRemain'][] = empty(count($last30daysLoginPlayer)) ? 0 : round( count($intersect30daysLoginPlayer) / count($last30daysLoginPlayer), 4) * 100; //30天留存率
  193. }
  194. $ret = json_encode($data);
  195. if($isCache == 1) {
  196. oo::commonOprRedis('common')->set($cacheKey, $ret);
  197. oo::commonOprRedis('common')->expireAt($cacheKey, strtotime('23:59:59'));
  198. }
  199. return $ret;
  200. }
  201. /**
  202. * 计算所有玩家
  203. * type 1 新注册 其他登陆
  204. */
  205. protected function getAllPlayer($date, $type)
  206. {
  207. $sidList = $this->_sidList;
  208. $total = oo::commonOprModel('statistics')->getAllPlayer($date, $type, $sidList);
  209. return $total;
  210. }
  211. /**
  212. * 获取该日期的设备号集合
  213. * @param $date
  214. * @param $type
  215. */
  216. protected function getAllDevicePlayer($date, $type)
  217. {
  218. $loginDeviceKey = oo::commonOprModel('statistics')->loginDeviceKey($date, $type);
  219. $data = oo::commonOprRedis('statistics')->sMembers($loginDeviceKey);
  220. return $data;
  221. }
  222. }