AnalyseLogic.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. <?php
  2. // 玩家日志逻
  3. namespace app\v1\logic\gameLog;
  4. use app\v1\logic\tool\ToolLogic;
  5. use plugin\saiadmin\basic\BaseLogic;
  6. use support\think\Db;
  7. class AnalyseLogic extends BaseLogic
  8. {
  9. // 注册按日
  10. public function getRegDayDataList($where){
  11. $params = $this->searchByAuth($where);
  12. $whereSql = $this->generateWhereSql($params);
  13. $field = "SUM(reg_total) AS reg_total, tdate,game_id";
  14. $baseData = $this->generateYearUnionList('base_total_day_',$where['reg_date'],$whereSql,$field,'game_id,tdate');
  15. $data=[];
  16. foreach($baseData as $row){
  17. $tdate = $row['tdate'];
  18. $game_id = $row['game_id'];
  19. $data[$game_id][$tdate] = $row['reg_total'];
  20. $data[$game_id]['total'] = !empty($data[$game_id]['total']) ? $data[$game_id]['total'] + $row['reg_total'] : $row['reg_total'];
  21. $data[$game_id]['game_id'] = $game_id;
  22. }
  23. $list = array_values($data);
  24. $totalRow = ['game_id'=>'合计'];
  25. foreach($list as &$row){
  26. $totalRow['total'] = !empty($totalRow['total']) ? $totalRow['total'] + $row['total'] : $row['total'];
  27. foreach ($row as $key => $value) {
  28. if($key == 'total' || $key == 'game_id'){
  29. continue;
  30. }
  31. $totalRow[$key] = !empty($totalRow[$key]) ? $totalRow[$key] + $value : $value;
  32. }
  33. }
  34. // 获取两个注册日期之间的日期列表
  35. $dateList = ToolLogic::getDatesBetween($where['reg_date'][0],$where['reg_date'][1]);
  36. $columnsData = [
  37. [
  38. 'title' => '游戏ID',
  39. 'dataIndex' => 'game_id',
  40. 'width' => 120,
  41. ],
  42. [
  43. 'title' => '游戏',
  44. 'dataIndex' => 'game_name',
  45. 'width' => 120,
  46. ],
  47. [
  48. 'title' => '合计',
  49. 'dataIndex' => 'total',
  50. 'width' => 120,
  51. ]
  52. ];
  53. foreach($dateList as $date){
  54. $columnsData[] = [
  55. 'title' => $date,
  56. 'dataIndex' => $date,
  57. 'width' => 120,
  58. ];
  59. }
  60. $result['data'] = $list;
  61. $result['totalRow'] = $totalRow;
  62. $result['columns'] = $columnsData;
  63. return $result;
  64. }
  65. // 注册按时
  66. public function getRegHourDataList($where){
  67. $params = $this->searchByAuth($where);
  68. $field = "SUM(role_create_user) AS role_create_user, tdate,game_id,thour";
  69. $regDate = $where['reg_date'];
  70. // 将$regDate转化为年月格式,如202509
  71. $ym = date('Ym', strtotime($regDate));
  72. $tableName = 'base_total_hour_'.$ym;
  73. $whereSql = 'WHERE 1=1';
  74. if(!empty($params['game_id'])){
  75. $whereSql .= " AND game_id IN(" . implode(',', $params['game_id']) . ")";
  76. }
  77. if(!empty($params['reg_date'])){
  78. $whereSql .= " AND tdate = '" .$params['reg_date']. "'";
  79. }
  80. $sql = "SELECT {$field} FROM {$tableName} {$whereSql} GROUP BY game_id,thour,tdate";
  81. $baseData = Db::connect('db_data_report')->query($sql);
  82. $data = [];
  83. foreach($baseData as &$row){
  84. $game_id = $row['game_id'];
  85. $thour = $row['thour'];
  86. $data[$game_id]['h'.$thour] = $row['role_create_user'];
  87. $data[$game_id]['total'] = !empty($data[$game_id]['total']) ? $data[$game_id]['total'] + $row['role_create_user'] : $row['role_create_user'];
  88. $data[$game_id]['game_id'] = $game_id;
  89. }
  90. $list = array_values($data);
  91. $totalRow = ['game_id'=>'合计'];
  92. foreach($list as &$row){
  93. $totalRow['total'] = !empty($totalRow['total']) ? $totalRow['total'] + $row['total'] : $row['total'];
  94. foreach ($row as $key => $value) {
  95. if($key == 'total' || $key == 'game_id'){
  96. continue;
  97. }
  98. $totalRow[$key] = !empty($totalRow[$key]) ? $totalRow[$key] + $value : $value;
  99. }
  100. }
  101. $result['data'] = $list;
  102. $result['totalRow'] = $totalRow;
  103. return $result;
  104. }
  105. // 留存按日
  106. public function getRetentionDayDataList($where){
  107. $params = $this->searchByAuth($where);
  108. // 构建whereSql
  109. $whereSql = '';
  110. if(!empty($params['game_id'])){
  111. $whereSql .= " AND game_id IN(" . implode(',', $params['game_id']) . ")";
  112. }
  113. if(!empty($params['reg_date'])){
  114. $whereSql .= " AND tdate BETWEEN '{$params['reg_date'][0]}' AND '{$params['reg_date'][1]}'";
  115. }
  116. $data = [];
  117. $totalRow = ['game_id'=>'合计'];
  118. $baseField = "SUM(reg_total) AS reg_total, tdate,game_id";
  119. $activeField = "SUM(active_total) AS active_total, reg_date,game_id,days";
  120. // 1. 查询每天的注册数,根据注册时间,游戏
  121. $baseData = $this->generateYearUnionList('base_total_day_',$params['reg_date'],$whereSql,$baseField,'game_id,tdate');
  122. $baseData = array_column($baseData,null,'tdate');
  123. // 2. 查询每天的活跃数,根据注册时间,游戏,留存天数
  124. $activeWhereSql = str_replace("AND tdate", "AND reg_date", $whereSql);
  125. if(!empty($params['days'])){
  126. $activeWhereSql .= " AND days = {$params['days']}";
  127. }
  128. $activeData = $this->generateYearUnionList('game_active_day_',$params['reg_date'],$activeWhereSql,$activeField,'game_id,reg_date');
  129. $activeData = array_column($activeData,null,'reg_date');
  130. foreach($baseData as $row){
  131. $game_id = $row['game_id'];
  132. $tdate = $row['tdate'];
  133. $data[$game_id]['game_id'] = $game_id;
  134. $data[$game_id][$tdate]['reg_total'] = $row['reg_total'];
  135. $data[$game_id][$tdate]['active_total'] = !empty($activeData[$tdate]['active_total']) ? $activeData[$tdate]['active_total'] : 0;
  136. $data[$game_id][$tdate]['retention_total'] = ToolLogic::getPercent($data[$game_id][$tdate]['active_total'],$data[$game_id][$tdate]['reg_total']);
  137. // 每日合计
  138. $data[$game_id]['total_reg_total'] = !empty($data[$game_id]['total_reg_total']) ? $data[$game_id]['total_reg_total'] + $data[$game_id][$tdate]['reg_total'] : $data[$game_id][$tdate]['reg_total'];
  139. $data[$game_id]['total_active_total'] = !empty($data[$game_id]['total_active_total']) ? $data[$game_id]['total_active_total'] + $data[$game_id][$tdate]['active_total'] : $data[$game_id][$tdate]['active_total'];
  140. // 底部合计
  141. $totalRow['total_reg_total'] = !empty($totalRow['total_reg_total']) ? $totalRow['total_reg_total'] + $data[$game_id][$tdate]['reg_total'] : $data[$game_id][$tdate]['reg_total'];
  142. $totalRow['total_active_total'] = !empty($totalRow['total_active_total']) ? $totalRow['total_active_total'] + $data[$game_id][$tdate]['active_total'] : $data[$game_id][$tdate]['active_total'];
  143. $totalRow[$tdate]['reg_total'] = !empty($totalRow[$tdate]['reg_total']) ? $totalRow[$tdate]['reg_total'] + $data[$game_id][$tdate]['reg_total'] : $data[$game_id][$tdate]['reg_total'];
  144. $totalRow[$tdate]['active_total'] = !empty($totalRow[$tdate]['active_total']) ? $totalRow[$tdate]['active_total'] + $data[$game_id][$tdate]['active_total'] : $data[$game_id][$tdate]['active_total'];
  145. }
  146. $data = array_values($data);
  147. foreach($data as &$row){
  148. foreach($row as $key => $value){
  149. if($key == 'total_reg_total' || $key == 'game_id'){
  150. continue;
  151. }
  152. if($key == 'total_active_total'){
  153. $row['total'] = ToolLogic::getPercent($row['total_active_total'],$row['total_reg_total']);
  154. }else{
  155. $row[$key] = ToolLogic::getPercent($value['active_total'],$value['reg_total']);
  156. }
  157. }
  158. }
  159. foreach($totalRow as $totalKey => &$row){
  160. if($totalKey == 'game_id' || $totalKey == 'total_active_total'||$totalKey == 'total_reg_total'){
  161. continue;
  162. }
  163. $totalRow[$totalKey] = ToolLogic::getPercent($row['active_total'],$row['reg_total']);
  164. }
  165. $totalRow['total'] = ToolLogic::getPercent($totalRow['total_active_total'],$totalRow['total_reg_total']);
  166. // 获取两个注册日期之间的日期列表
  167. $dateList = ToolLogic::getDatesBetween($where['reg_date'][0],$where['reg_date'][1]);
  168. $columnsData = [
  169. [
  170. 'title' => '游戏ID',
  171. 'dataIndex' => 'game_id',
  172. 'width' => 120,
  173. ],
  174. [
  175. 'title' => '游戏',
  176. 'dataIndex' => 'game_name',
  177. 'width' => 120,
  178. ],
  179. [
  180. 'title' => '合计',
  181. 'dataIndex' => 'total',
  182. 'width' => 120,
  183. ]
  184. ];
  185. foreach($dateList as $date){
  186. $columnsData[] = [
  187. 'title' => $date,
  188. 'dataIndex' => $date,
  189. 'width' => 120,
  190. ];
  191. }
  192. $result['data'] = $data;
  193. $result['totalRow'] = $totalRow;
  194. $result['columns'] = $columnsData;
  195. return $result;
  196. }
  197. /*
  198. 数据总览
  199. 1. DAU 登陆总数 login_total
  200. 2. ARPU pay_total/pay_num
  201. */
  202. public function getDataOverview($where){
  203. $params = $this->searchByAuth($where);
  204. $whereSql = $this->generateWhereSql($params);
  205. // 基础汇总信息
  206. $field = "
  207. SUM(login_total) AS login_total, -- 登陆总数
  208. SUM(reg_total) AS reg_total, -- 注册总数
  209. SUM(pay_total) AS pay_total, -- 付费总数
  210. SUM(pay_num) AS pay_num, -- 付费人数
  211. SUM(reg_login_total) AS reg_login_total, -- 注册登陆总数
  212. SUM(reg_pay_num) AS reg_pay_num, -- 注册付费数
  213. SUM(reg_pay_total) AS reg_pay_total, -- 注册付费金额
  214. SUM(old_login_total) AS old_login_total, -- 老用户登陆总数
  215. tdate";
  216. $baseData = $this->generateYearUnionList('base_total_day_',$where['reg_date'],$whereSql,$field,'tdate');
  217. if(empty($baseData)){
  218. return [
  219. 'data' => [],
  220. 'totalRow' => []
  221. ];
  222. }
  223. $actWhereSql = str_replace("AND tdate", "AND reg_date", $whereSql);
  224. $actWhereSql .= " AND days = 1";
  225. $actData = $this->generateYearUnionList('game_active_day_',$where['reg_date'],$actWhereSql,'SUM(active_total) AS active_total,reg_date','reg_date');
  226. $actData = array_column($actData,null,'reg_date');
  227. $totalRow = [
  228. 'tdate' => '合计'
  229. ];
  230. foreach($baseData as &$row){
  231. $totalRow['login_total'] = !empty($totalRow['login_total']) ? $totalRow['login_total'] + $row['login_total'] : $row['login_total']; // 总用户 - 登陆总数
  232. $totalRow['reg_login_total'] = !empty($totalRow['reg_login_total']) ? $totalRow['reg_login_total'] + $row['reg_login_total'] : $row['reg_login_total']; // 新用户 - 注册登陆总数
  233. $totalRow['pay_num'] = !empty($totalRow['pay_num']) ? $totalRow['pay_num'] + $row['pay_num'] : $row['pay_num']; // 总用户 - 付费人数
  234. $totalRow['pay_total'] = !empty($totalRow['pay_total']) ? $totalRow['pay_total'] + $row['pay_total'] : $row['pay_total']; // 总用户 - 付费金额
  235. $totalRow['old_login_total'] = !empty($totalRow['old_login_total']) ? $totalRow['old_login_total'] + $row['old_login_total'] : $row['old_login_total']; // 老用户 - 登陆总数
  236. $totalRow['reg_total'] = !empty($totalRow['reg_total']) ? $totalRow['reg_total'] + $row['reg_total'] : $row['reg_total']; // 新用户 - 注册总数
  237. $totalRow['reg_pay_num'] = !empty($totalRow['reg_pay_num']) ? $totalRow['reg_pay_num'] + $row['reg_pay_num'] : $row['reg_pay_num']; // 新用户 - 注册付费数
  238. $totalRow['reg_pay_total'] = !empty($totalRow['reg_pay_total']) ? $totalRow['reg_pay_total'] + $row['reg_pay_total'] : $row['reg_pay_total']; // 新用户 - 注册付费金额
  239. $totalRow['active'] = !empty($totalRow['active']) ? $totalRow['active'] + $actData[$row['tdate']]['active_total']??0 : $actData[$row['tdate']]['active_total']??0; // 次留数
  240. $row['active'] = !empty($actData[$row['tdate']]['active_total']) ? $actData[$row['tdate']]['active_total'] : 0; // 次留数
  241. $row['arpu'] = ToolLogic::getRound($row['pay_total'],$row['pay_num']); // 总用户 - ARPU
  242. $row['pay_rate'] = ToolLogic::getPercent($row['pay_num'],$row['login_total']); // 总用户 - 付费率
  243. $row['reg_pay_rate'] = ToolLogic::getPercent($row['reg_pay_num'],$row['reg_total']); // 新用户 - 注册付费率
  244. $row['reg_arpu'] = ToolLogic::getRound($row['reg_pay_total'],$row['reg_pay_num']); // 新用户 - 注册付费ARPU
  245. $row['act_rate'] = ToolLogic::getPercent($row['active'],$row['reg_total']); // 新用户 - 次留率
  246. $row['old_pay_num'] = $row['pay_num'] - $row['reg_pay_num']; // 老用户 - 付费人数
  247. $row['old_pay_total'] = $row['pay_total'] - $row['reg_pay_total']; // 老用户 - 付费金额
  248. $row['old_pay_rate'] = ToolLogic::getPercent($row['old_pay_num'],$row['old_login_total']); // 老用户 - 付费率
  249. $row['old_arpu'] = ToolLogic::getRound($row['old_pay_total'],$row['old_pay_num']); // 老用户 - 付费ARPU
  250. }
  251. $totalRow['arpu'] = ToolLogic::getRound($totalRow['pay_total'],$totalRow['pay_num']); // 总用户 - ARPU
  252. $totalRow['pay_rate'] = ToolLogic::getPercent($totalRow['pay_num'],$totalRow['login_total']); // 总用户 - 付费率
  253. $totalRow['reg_pay_rate'] = ToolLogic::getPercent($totalRow['reg_pay_num'],$totalRow['reg_total']); // 新用户 - 注册付费率
  254. $totalRow['reg_arpu'] = ToolLogic::getRound($totalRow['reg_pay_total'],$totalRow['reg_pay_num']); // 新用户 - 注册付费ARPU
  255. $totalRow['old_pay_num'] = $totalRow['pay_num'] - $totalRow['reg_pay_num']; // 老用户 - 付费人数
  256. $totalRow['old_pay_total'] = $totalRow['pay_total'] - $totalRow['reg_pay_total']; // 老用户 - 付费金额
  257. $totalRow['old_pay_rate'] = ToolLogic::getPercent($totalRow['old_pay_num'],$totalRow['old_login_total']); // 老用户 - 付费率
  258. $totalRow['old_arpu'] = ToolLogic::getRound($totalRow['old_pay_total'],$totalRow['old_pay_num']); // 老用户 - 付费ARPU
  259. $totalRow['act_rate'] = ToolLogic::getPercent($totalRow['active'],$totalRow['reg_total']); // 次留率
  260. return [
  261. 'data' => $baseData,
  262. 'totalRow' => $totalRow
  263. ];
  264. }
  265. // 生成基础日统计表的联合查询列表
  266. public function generateYearUnionList($namePrefix, $regDate,$whereSql='',$field='*',$group=null){
  267. $tableNames = ToolLogic::getYearlyTableNames($namePrefix, $regDate[0],$regDate[1]);
  268. $sqlParts = [];
  269. foreach ($tableNames as $tableName){
  270. $sqlParts[] = "SELECT * FROM {$tableName} WHERE 1=1 {$whereSql}";
  271. }
  272. $unionSql = implode(" UNION ALL ", $sqlParts);
  273. $finalSql = "
  274. SELECT {$field} FROM ( {$unionSql} ) AS all_total_day
  275. ";
  276. if (!empty($group)) {
  277. $finalSql .= " GROUP BY {$group}";
  278. }
  279. $baseData = Db::connect('db_data_report')->query($finalSql);
  280. return $baseData;
  281. }
  282. // 生成wheresql
  283. public function generateWhereSql($params){
  284. $whereSql = "";
  285. // 游戏id
  286. if(!empty($params['game_id'])){
  287. if (is_array($params['game_id'])) {
  288. $whereSql .= " AND game_id IN(" . implode(',', $params['game_id']) . ")";
  289. } else {
  290. $whereSql .= " AND game_id = {$params['game_id']}";
  291. }
  292. }
  293. // 媒体id
  294. if(!empty($params['media_id'])){
  295. $whereSql .= " AND media_id = {$params['media_id']}";
  296. }
  297. // 渠道id
  298. if(!empty($params['agent_id'])){
  299. $whereSql .= " AND agent_id = {$params['agent_id']}";
  300. }
  301. // 广告位id
  302. if(!empty($params['site_id'])){
  303. if (is_array($params['site_id'])) {
  304. $whereSql .= " AND site_id IN(" . implode(',', $params['site_id']) . ")";
  305. } else {
  306. $whereSql .= " AND site_id = {$params['site_id']}";
  307. }
  308. }
  309. // 负责人
  310. if(!empty($params['auth_id'])){
  311. if (is_array($params['auth_id'])) {
  312. $whereSql .= " AND auth_id IN(" . implode(',', $params['auth_id']) . ")";
  313. } else {
  314. $whereSql .= " AND auth_id = {$params['auth_id']}";
  315. }
  316. }
  317. // 注册日期
  318. if(!empty($params['reg_date'])??null){
  319. $whereSql .= " AND tdate BETWEEN '{$params['reg_date'][0]}' AND '{$params['reg_date'][1]}'";
  320. }
  321. return $whereSql;
  322. }
  323. }