AnalyseLogic.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. <?php
  2. // 玩家日志逻
  3. namespace app\v1\logic\gameLog;
  4. use app\v1\logic\tool\ToolLogic;
  5. use plugin\saiadmin\basic\BaseLogic;
  6. use plugin\saiadmin\exception\ApiException;
  7. use support\think\Db;
  8. class AnalyseLogic extends BaseLogic
  9. {
  10. // 注册按日
  11. public function getRegDayDataList($where){
  12. $params = $this->searchByAuth($where);
  13. $whereSql = $this->generateWhereSql($params);
  14. $field = "SUM(reg_total) AS reg_total, tdate,game_id";
  15. $baseData = $this->generateYearUnionList('base_total_day_',$where['reg_date'],$whereSql,$field,'game_id,tdate');
  16. $data=[];
  17. foreach($baseData as $row){
  18. $tdate = $row['tdate'];
  19. $game_id = $row['game_id'];
  20. $data[$game_id][$tdate] = $row['reg_total'];
  21. $data[$game_id]['total'] = !empty($data[$game_id]['total']) ? $data[$game_id]['total'] + $row['reg_total'] : $row['reg_total'];
  22. $data[$game_id]['game_id'] = $game_id;
  23. }
  24. $list = array_values($data);
  25. $totalRow = ['game_id'=>'合计'];
  26. foreach($list as &$row){
  27. $totalRow['total'] = !empty($totalRow['total']) ? $totalRow['total'] + $row['total'] : $row['total'];
  28. foreach ($row as $key => $value) {
  29. if($key == 'total' || $key == 'game_id'){
  30. continue;
  31. }
  32. $totalRow[$key] = !empty($totalRow[$key]) ? $totalRow[$key] + $value : $value;
  33. }
  34. }
  35. // 获取两个注册日期之间的日期列表
  36. $dateList = ToolLogic::getDatesBetween($where['reg_date'][0],$where['reg_date'][1]);
  37. $columnsData = [
  38. [
  39. 'title' => '游戏ID',
  40. 'dataIndex' => 'game_id',
  41. 'width' => 120,
  42. ],
  43. [
  44. 'title' => '游戏',
  45. 'dataIndex' => 'game_name',
  46. 'width' => 120,
  47. ],
  48. [
  49. 'title' => '合计',
  50. 'dataIndex' => 'total',
  51. 'width' => 120,
  52. ]
  53. ];
  54. foreach($dateList as $date){
  55. $columnsData[] = [
  56. 'title' => $date,
  57. 'dataIndex' => $date,
  58. 'width' => 120,
  59. ];
  60. }
  61. $result['data'] = $list;
  62. $result['totalRow'] = $totalRow;
  63. $result['columns'] = $columnsData;
  64. return $result;
  65. }
  66. // 注册按时
  67. public function getRegHourDataList($where){
  68. $params = $this->searchByAuth($where);
  69. $field = "SUM(role_create_user) AS role_create_user, tdate,game_id,thour";
  70. $regDate = $where['reg_date'];
  71. // 将$regDate转化为年月格式,如202509
  72. $ym = date('Ym', strtotime($regDate));
  73. $tableName = 'base_total_hour_'.$ym;
  74. $whereSql = 'WHERE 1=1';
  75. if(!empty($params['game_id'])){
  76. $whereSql .= " AND game_id IN(" . implode(',', $params['game_id']) . ")";
  77. }
  78. if(!empty($params['reg_date'])){
  79. $whereSql .= " AND tdate = '" .$params['reg_date']. "'";
  80. }
  81. $sql = "SELECT {$field} FROM {$tableName} {$whereSql} GROUP BY game_id,thour,tdate";
  82. $baseData = Db::connect('db_data_report')->query($sql);
  83. $data = [];
  84. foreach($baseData as &$row){
  85. $game_id = $row['game_id'];
  86. $thour = $row['thour'];
  87. $data[$game_id]['h'.$thour] = $row['role_create_user'];
  88. $data[$game_id]['total'] = !empty($data[$game_id]['total']) ? $data[$game_id]['total'] + $row['role_create_user'] : $row['role_create_user'];
  89. $data[$game_id]['game_id'] = $game_id;
  90. }
  91. $list = array_values($data);
  92. $totalRow = ['game_id'=>'合计'];
  93. foreach($list as &$row){
  94. $totalRow['total'] = !empty($totalRow['total']) ? $totalRow['total'] + $row['total'] : $row['total'];
  95. foreach ($row as $key => $value) {
  96. if($key == 'total' || $key == 'game_id'){
  97. continue;
  98. }
  99. $totalRow[$key] = !empty($totalRow[$key]) ? $totalRow[$key] + $value : $value;
  100. }
  101. }
  102. $result['data'] = $list;
  103. $result['totalRow'] = $totalRow;
  104. return $result;
  105. }
  106. // 留存按日
  107. public function getRetentionDayDataList($where){
  108. $params = $this->searchByAuth($where);
  109. // 构建whereSql
  110. $whereSql = '';
  111. if(!empty($params['game_id'])){
  112. $whereSql .= " AND game_id IN(" . implode(',', $params['game_id']) . ")";
  113. }
  114. if(!empty($params['reg_date'])){
  115. $whereSql .= " AND tdate BETWEEN '{$params['reg_date'][0]}' AND '{$params['reg_date'][1]}'";
  116. }
  117. $data = [];
  118. $totalRow = ['game_id'=>'合计'];
  119. $baseField = "SUM(reg_total) AS reg_total, tdate,game_id";
  120. $activeField = "SUM(active_total) AS active_total, reg_date,game_id,days";
  121. // 1. 查询每天的注册数,根据注册时间,游戏
  122. $baseData = $this->generateYearUnionList('base_total_day_',$params['reg_date'],$whereSql,$baseField,'game_id,tdate');
  123. $baseData = array_column($baseData,null,'tdate');
  124. // 2. 查询每天的活跃数,根据注册时间,游戏,留存天数
  125. $activeWhereSql = str_replace("AND tdate", "AND reg_date", $whereSql);
  126. if(!empty($params['days'])){
  127. $activeWhereSql .= " AND days = {$params['days']}";
  128. }
  129. $activeData = $this->generateYearUnionList('game_active_day_',$params['reg_date'],$activeWhereSql,$activeField,'game_id,reg_date');
  130. $activeData = array_column($activeData,null,'reg_date');
  131. foreach($baseData as $row){
  132. $game_id = $row['game_id'];
  133. $tdate = $row['tdate'];
  134. $data[$game_id]['game_id'] = $game_id;
  135. $data[$game_id][$tdate]['reg_total'] = $row['reg_total'];
  136. $data[$game_id][$tdate]['active_total'] = !empty($activeData[$tdate]['active_total']) ? $activeData[$tdate]['active_total'] : 0;
  137. $data[$game_id][$tdate]['retention_total'] = ToolLogic::getPercent($data[$game_id][$tdate]['active_total'],$data[$game_id][$tdate]['reg_total']);
  138. // 每日合计
  139. $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'];
  140. $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'];
  141. // 底部合计
  142. $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'];
  143. $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'];
  144. $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'];
  145. $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'];
  146. }
  147. $data = array_values($data);
  148. foreach($data as &$row){
  149. foreach($row as $key => $value){
  150. if($key == 'total_reg_total' || $key == 'game_id'){
  151. continue;
  152. }
  153. if($key == 'total_active_total'){
  154. $row['total'] = ToolLogic::getPercent($row['total_active_total'],$row['total_reg_total']);
  155. }else{
  156. $row[$key] = ToolLogic::getPercent($value['active_total'],$value['reg_total']);
  157. }
  158. }
  159. }
  160. foreach($totalRow as $totalKey => &$row){
  161. if($totalKey == 'game_id' || $totalKey == 'total_active_total'||$totalKey == 'total_reg_total'){
  162. continue;
  163. }
  164. $totalRow[$totalKey] = ToolLogic::getPercent($row['active_total'],$row['reg_total']);
  165. }
  166. $totalRow['total'] = ToolLogic::getPercent($totalRow['total_active_total'],$totalRow['total_reg_total']);
  167. // 获取两个注册日期之间的日期列表
  168. $dateList = ToolLogic::getDatesBetween($where['reg_date'][0],$where['reg_date'][1]);
  169. $columnsData = [
  170. [
  171. 'title' => '游戏ID',
  172. 'dataIndex' => 'game_id',
  173. 'width' => 120,
  174. ],
  175. [
  176. 'title' => '游戏',
  177. 'dataIndex' => 'game_name',
  178. 'width' => 120,
  179. ],
  180. [
  181. 'title' => '合计',
  182. 'dataIndex' => 'total',
  183. 'width' => 120,
  184. ]
  185. ];
  186. foreach($dateList as $date){
  187. $columnsData[] = [
  188. 'title' => $date,
  189. 'dataIndex' => $date,
  190. 'width' => 120,
  191. ];
  192. }
  193. $result['data'] = $data;
  194. $result['totalRow'] = $totalRow;
  195. $result['columns'] = $columnsData;
  196. return $result;
  197. }
  198. /*
  199. 数据总览
  200. */
  201. public function getDataOverview($where){
  202. $params = $this->searchByAuth($where);
  203. $whereSql = $this->generateWhereSql($params);
  204. // 基础汇总信息
  205. $field = "
  206. SUM(login_total) AS login_total, -- 登陆总数
  207. SUM(reg_total) AS reg_total, -- 注册总数
  208. SUM(pay_total) AS pay_total, -- 付费总数
  209. SUM(pay_num) AS pay_num, -- 付费人数
  210. SUM(reg_login_total) AS reg_login_total, -- 注册登陆总数
  211. SUM(reg_pay_num) AS reg_pay_num, -- 注册付费数
  212. SUM(reg_pay_total) AS reg_pay_total, -- 注册付费金额
  213. SUM(old_login_total) AS old_login_total, -- 老用户登陆总数
  214. tdate";
  215. $baseData = $this->generateYearUnionList('base_total_day_',$where['reg_date'],$whereSql,$field,'tdate');
  216. if(empty($baseData)){
  217. return [
  218. 'data' => [],
  219. 'totalRow' => []
  220. ];
  221. }
  222. $actWhereSql = str_replace("AND tdate", "AND reg_date", $whereSql);
  223. $actWhereSql .= " AND days = 1";
  224. $actData = $this->generateYearUnionList('game_active_day_',$where['reg_date'],$actWhereSql,'SUM(active_total) AS active_total,reg_date','reg_date');
  225. $actData = array_column($actData,null,'reg_date');
  226. $totalRow = [
  227. 'tdate' => '合计'
  228. ];
  229. foreach($baseData as &$row){
  230. $totalRow['login_total'] = !empty($totalRow['login_total']) ? $totalRow['login_total'] + $row['login_total'] : $row['login_total']; // 总用户 - 登陆总数
  231. $totalRow['reg_login_total'] = !empty($totalRow['reg_login_total']) ? $totalRow['reg_login_total'] + $row['reg_login_total'] : $row['reg_login_total']; // 新用户 - 注册登陆总数
  232. $totalRow['pay_num'] = !empty($totalRow['pay_num']) ? $totalRow['pay_num'] + $row['pay_num'] : $row['pay_num']; // 总用户 - 付费人数
  233. $totalRow['pay_total'] = !empty($totalRow['pay_total']) ? $totalRow['pay_total'] + $row['pay_total'] : $row['pay_total']; // 总用户 - 付费金额
  234. $totalRow['old_login_total'] = !empty($totalRow['old_login_total']) ? $totalRow['old_login_total'] + $row['old_login_total'] : $row['old_login_total']; // 老用户 - 登陆总数
  235. $totalRow['reg_total'] = !empty($totalRow['reg_total']) ? $totalRow['reg_total'] + $row['reg_total'] : $row['reg_total']; // 新用户 - 注册总数
  236. $totalRow['reg_pay_num'] = !empty($totalRow['reg_pay_num']) ? $totalRow['reg_pay_num'] + $row['reg_pay_num'] : $row['reg_pay_num']; // 新用户 - 注册付费数
  237. $totalRow['reg_pay_total'] = !empty($totalRow['reg_pay_total']) ? $totalRow['reg_pay_total'] + $row['reg_pay_total'] : $row['reg_pay_total']; // 新用户 - 注册付费金额
  238. $totalRow['active'] = !empty($totalRow['active']) ? $totalRow['active'] + $actData[$row['tdate']]['active_total']??0 : $actData[$row['tdate']]['active_total']??0; // 次留数
  239. $row['active'] = !empty($actData[$row['tdate']]['active_total']) ? $actData[$row['tdate']]['active_total'] : 0; // 次留数
  240. $row['arpu'] = ToolLogic::getRound($row['pay_total'],$row['pay_num']); // 总用户 - ARPU
  241. $row['pay_rate'] = ToolLogic::getPercent($row['pay_num'],$row['login_total']); // 总用户 - 付费率
  242. $row['reg_pay_rate'] = ToolLogic::getPercent($row['reg_pay_num'],$row['reg_total']); // 新用户 - 注册付费率
  243. $row['reg_arpu'] = ToolLogic::getRound($row['reg_pay_total'],$row['reg_pay_num']); // 新用户 - 注册付费ARPU
  244. $row['act_rate'] = ToolLogic::getPercent($row['active'],$row['reg_total']); // 新用户 - 次留率
  245. $row['old_pay_num'] = $row['pay_num'] - $row['reg_pay_num']; // 老用户 - 付费人数
  246. $row['old_pay_total'] = $row['pay_total'] - $row['reg_pay_total']; // 老用户 - 付费金额
  247. $row['old_pay_rate'] = ToolLogic::getPercent($row['old_pay_num'],$row['old_login_total']); // 老用户 - 付费率
  248. $row['old_arpu'] = ToolLogic::getRound($row['old_pay_total'],$row['old_pay_num']); // 老用户 - 付费ARPU
  249. }
  250. $totalRow['arpu'] = ToolLogic::getRound($totalRow['pay_total'],$totalRow['pay_num']); // 总用户 - ARPU
  251. $totalRow['pay_rate'] = ToolLogic::getPercent($totalRow['pay_num'],$totalRow['login_total']); // 总用户 - 付费率
  252. $totalRow['reg_pay_rate'] = ToolLogic::getPercent($totalRow['reg_pay_num'],$totalRow['reg_total']); // 新用户 - 注册付费率
  253. $totalRow['reg_arpu'] = ToolLogic::getRound($totalRow['reg_pay_total'],$totalRow['reg_pay_num']); // 新用户 - 注册付费ARPU
  254. $totalRow['old_pay_num'] = $totalRow['pay_num'] - $totalRow['reg_pay_num']; // 老用户 - 付费人数
  255. $totalRow['old_pay_total'] = $totalRow['pay_total'] - $totalRow['reg_pay_total']; // 老用户 - 付费金额
  256. $totalRow['old_pay_rate'] = ToolLogic::getPercent($totalRow['old_pay_num'],$totalRow['old_login_total']); // 老用户 - 付费率
  257. $totalRow['old_arpu'] = ToolLogic::getRound($totalRow['old_pay_total'],$totalRow['old_pay_num']); // 老用户 - 付费ARPU
  258. $totalRow['act_rate'] = ToolLogic::getPercent($totalRow['active'],$totalRow['reg_total']); // 次留率
  259. return [
  260. 'data' => $baseData,
  261. 'totalRow' => $totalRow
  262. ];
  263. }
  264. /*
  265. 数据总览(按月)
  266. */
  267. public function getDataOverviewByMonth($where){
  268. $params = $this->searchByAuth($where);
  269. // 根据渠道名称获取渠道ID
  270. if(!empty($params['agent_name'])){
  271. $agentData = Db::connect('db_advert')->query("SELECT id,name FROM agent_list WHERE 1=1 AND name = '{$params['agent_name']}'");
  272. $params['agent_id'] = $agentData[0]['id'] ?? 0;
  273. }
  274. $whereSql = $this->generateWhereSql($params);
  275. // 基础汇总信息
  276. $field = "
  277. SUM(login_total) AS login_total, -- 登陆总数
  278. SUM(reg_total) AS reg_total, -- 注册总数
  279. SUM(pay_total) AS pay_total, -- 付费总数
  280. SUM(pay_num) AS pay_num, -- 付费人数
  281. SUM(reg_login_total) AS reg_login_total, -- 注册登陆总数
  282. SUM(reg_pay_num) AS reg_pay_num, -- 注册付费数
  283. SUM(reg_pay_total) AS reg_pay_total, -- 注册付费金额
  284. SUM(old_login_total) AS old_login_total, -- 老用户登陆总数
  285. date_format(`tdate`, '%Y-%m') AS mdate";
  286. $baseData = $this->generateYearUnionList('base_total_day_',$where['reg_date'],$whereSql,$field,'mdate');
  287. if(empty($baseData)){
  288. return [
  289. 'data' => [],
  290. 'totalRow' => []
  291. ];
  292. }
  293. $actWhereSql = str_replace("AND tdate", "AND reg_date", $whereSql);
  294. $actWhereSql .= " AND days = 1";
  295. $actData = $this->generateYearUnionList('game_active_day_',$where['reg_date'],$actWhereSql,'SUM(active_total) AS active_total,date_format(reg_date, "%Y-%m") AS mdate','mdate');
  296. $actData = array_column($actData,null,'mdate');
  297. $totalRow = [
  298. 'mdate' => '合计'
  299. ];
  300. foreach($baseData as &$row){
  301. $totalRow['login_total'] = !empty($totalRow['login_total']) ? $totalRow['login_total'] + $row['login_total'] : $row['login_total']; // 总用户 - 登陆总数
  302. $totalRow['reg_login_total'] = !empty($totalRow['reg_login_total']) ? $totalRow['reg_login_total'] + $row['reg_login_total'] : $row['reg_login_total']; // 新用户 - 注册登陆总数
  303. $totalRow['pay_num'] = !empty($totalRow['pay_num']) ? $totalRow['pay_num'] + $row['pay_num'] : $row['pay_num']; // 总用户 - 付费人数
  304. $totalRow['pay_total'] = !empty($totalRow['pay_total']) ? $totalRow['pay_total'] + $row['pay_total'] : $row['pay_total']; // 总用户 - 付费金额
  305. $totalRow['old_login_total'] = !empty($totalRow['old_login_total']) ? $totalRow['old_login_total'] + $row['old_login_total'] : $row['old_login_total']; // 老用户 - 登陆总数
  306. $totalRow['reg_total'] = !empty($totalRow['reg_total']) ? $totalRow['reg_total'] + $row['reg_total'] : $row['reg_total']; // 新用户 - 注册总数
  307. $totalRow['reg_pay_num'] = !empty($totalRow['reg_pay_num']) ? $totalRow['reg_pay_num'] + $row['reg_pay_num'] : $row['reg_pay_num']; // 新用户 - 注册付费数
  308. $totalRow['reg_pay_total'] = !empty($totalRow['reg_pay_total']) ? $totalRow['reg_pay_total'] + $row['reg_pay_total'] : $row['reg_pay_total']; // 新用户 - 注册付费金额
  309. $totalRow['active'] = !empty($totalRow['active']) ? $totalRow['active'] + $actData[$row['mdate']]['active_total']??0 : $actData[$row['mdate']]['active_total']??0; // 次留数
  310. $row['active'] = !empty($actData[$row['mdate']]['active_total']) ? $actData[$row['mdate']]['active_total'] : 0; // 次留数
  311. $row['arpu'] = ToolLogic::getRound($row['pay_total'],$row['pay_num']); // 总用户 - ARPU
  312. $row['pay_rate'] = ToolLogic::getPercent($row['pay_num'],$row['login_total']); // 总用户 - 付费率
  313. $row['reg_pay_rate'] = ToolLogic::getPercent($row['reg_pay_num'],$row['reg_total']); // 新用户 - 注册付费率
  314. $row['reg_arpu'] = ToolLogic::getRound($row['reg_pay_total'],$row['reg_pay_num']); // 新用户 - 注册付费ARPU
  315. $row['act_rate'] = ToolLogic::getPercent($row['active'],$row['reg_total']); // 新用户 - 次留率
  316. $row['old_pay_num'] = $row['pay_num'] - $row['reg_pay_num']; // 老用户 - 付费人数
  317. $row['old_pay_total'] = $row['pay_total'] - $row['reg_pay_total']; // 老用户 - 付费金额
  318. $row['old_pay_rate'] = ToolLogic::getPercent($row['old_pay_num'],$row['old_login_total']); // 老用户 - 付费率
  319. $row['old_arpu'] = ToolLogic::getRound($row['old_pay_total'],$row['old_pay_num']); // 老用户 - 付费ARPU
  320. }
  321. $totalRow['arpu'] = ToolLogic::getRound($totalRow['pay_total'],$totalRow['pay_num']); // 总用户 - ARPU
  322. $totalRow['pay_rate'] = ToolLogic::getPercent($totalRow['pay_num'],$totalRow['login_total']); // 总用户 - 付费率
  323. $totalRow['reg_pay_rate'] = ToolLogic::getPercent($totalRow['reg_pay_num'],$totalRow['reg_total']); // 新用户 - 注册付费率
  324. $totalRow['reg_arpu'] = ToolLogic::getRound($totalRow['reg_pay_total'],$totalRow['reg_pay_num']); // 新用户 - 注册付费ARPU
  325. $totalRow['old_pay_num'] = $totalRow['pay_num'] - $totalRow['reg_pay_num']; // 老用户 - 付费人数
  326. $totalRow['old_pay_total'] = $totalRow['pay_total'] - $totalRow['reg_pay_total']; // 老用户 - 付费金额
  327. $totalRow['old_pay_rate'] = ToolLogic::getPercent($totalRow['old_pay_num'],$totalRow['old_login_total']); // 老用户 - 付费率
  328. $totalRow['old_arpu'] = ToolLogic::getRound($totalRow['old_pay_total'],$totalRow['old_pay_num']); // 老用户 - 付费ARPU
  329. $totalRow['act_rate'] = ToolLogic::getPercent($totalRow['active'],$totalRow['reg_total']); // 次留率
  330. return [
  331. 'data' => $baseData,
  332. 'totalRow' => $totalRow
  333. ];
  334. }
  335. /**
  336. * 收入分析
  337. */
  338. public function getIncomeAnalysis($where){
  339. $params = $this->searchByAuth($where);
  340. $tdate = $params['reg_date']??date('Y-m-d');
  341. $ldate = date('Y-m-d', strtotime($tdate . ' -1 days'));
  342. $wdate = date('Y-m-d', strtotime($tdate . ' -7 days'));
  343. unset($params['reg_date']);
  344. $whereSql = $this->generateWhereSql($params);
  345. $whereSql .= " AND tdate IN ('{$tdate}','{$ldate}','{$wdate}')";
  346. $field = "
  347. SUM(pay_total) AS pay_total, -- 付费金额
  348. SUM(pay_num) AS pay_num, -- 付费人数
  349. SUM(login_total) AS login_total, -- 登陆总数
  350. game_id,
  351. tdate";
  352. $year = (int)date('Y', strtotime($tdate));
  353. $tableName = 'base_total_day_'.$year;
  354. $baseData = Db::connect('db_data_report')->query("SELECT {$field} FROM {$tableName} WHERE 1=1 {$whereSql} GROUP BY game_id,tdate");
  355. if(empty($baseData)){
  356. return [
  357. 'data' => [],
  358. 'totalRow' => []
  359. ];
  360. }
  361. // 计算今日,所有游戏总充值
  362. $totalRow = [
  363. 'game_id' => '合计',
  364. ];
  365. $allTotal = 0;
  366. $data = [];
  367. foreach($baseData as &$row){
  368. // 查询日期数据
  369. if($row['tdate'] == $tdate){
  370. $gameId = $row['game_id'];
  371. $data[$gameId]['game_id'] = $gameId;
  372. $data[$gameId]['login_total'] = $row['login_total']; // DAU
  373. $data[$gameId]['pay_total'] = $row['pay_total']??0; // 今日充值
  374. $data[$gameId]['pay_num'] = $row['pay_num']??0; // 今日付费人数
  375. $data[$gameId]['pay_arpu'] = ToolLogic::getRound($row['pay_total'],$row['pay_num']); // 今日付费ARPU
  376. $allTotal += $row['pay_total'];
  377. $totalRow['pay_total'] = !empty($totalRow['pay_total']) ? $totalRow['pay_total'] + $row['pay_total'] : $row['pay_total']; // 今日充值
  378. $totalRow['pay_num'] = !empty($totalRow['pay_num']) ? $totalRow['pay_num'] + $row['pay_num'] : $row['pay_num']; // 今日付费人数
  379. $totalRow['login_total'] = !empty($totalRow['login_total']) ? $totalRow['login_total'] + $row['login_total'] : $row['login_total']; // 今日登陆人数
  380. }
  381. // 查询昨天数据
  382. if($row['tdate'] == $ldate){
  383. $gameId = $row['game_id'];
  384. $data[$gameId]['yestoday_pay_total'] = $row['pay_total']??0; // 昨日充值
  385. $totalRow['yestoday_pay_total'] = !empty($totalRow['yestoday_pay_total']) ? $totalRow['yestoday_pay_total'] + $row['pay_total'] : $row['pay_total']; // 昨日充值
  386. }
  387. // 查询7天前数据
  388. if($row['tdate'] == $wdate){
  389. $gameId = $row['game_id'];
  390. $data[$gameId]['week_pay_total'] = $row['pay_total']??0; // 7天前充值
  391. $totalRow['week_pay_total'] = !empty($totalRow['week_pay_total']) ? $totalRow['week_pay_total'] + $row['pay_total'] : $row['pay_total']; // 7天前充值
  392. }
  393. }
  394. $totalRow['pay_arpu'] = ToolLogic::getRound($totalRow['pay_total'],$totalRow['pay_num']); // 今日充值ARPU
  395. $totalRow['pay_ratio'] = ToolLogic::getPercent($totalRow['pay_total'],$allTotal); // 今日充值占比
  396. $totalRow['pay_increase_yestoday'] = $totalRow['pay_total'] - $totalRow['yestoday_pay_total']; // 昨日增长
  397. $totalRow['pay_increase_week'] = $totalRow['pay_total'] - $totalRow['week_pay_total']; // 7天增长
  398. foreach($data as &$row){
  399. $row['pay_ratio'] = ToolLogic::getPercent($row['pay_total'],$allTotal); // 今日充值占比
  400. $row['pay_increase_yestoday'] = $row['pay_total'] - $row['yestoday_pay_total']; // 昨日增长
  401. $row['pay_increase_week'] = $row['pay_total'] - $row['week_pay_total']; // 7天增长
  402. }
  403. return [
  404. 'data' => array_values($data),
  405. 'totalRow' => $totalRow
  406. ];
  407. }
  408. /**
  409. * 付费留存
  410. * 1. 登录日志表:sdk_login_log_, 查找符合注册时间的用户, 获取用户id
  411. *
  412. * inner join ON login.uid = order.uid,
  413. *
  414. * 2. 根据用户id,去订单表,筛选出,次留、2留的日期为充值日期, 从而获取充值人数
  415. * 3. 根据注册时间,获取总的pay_num
  416. */
  417. public function getPayRetention($where){
  418. $params = $this->searchByAuth($where);
  419. // $whereSql = $this->generateWhereSql($params);
  420. // 判断不能超过90天查询
  421. $days = ToolLogic::getDays($where['reg_date'][0],$where['reg_date'][1]);
  422. if($days > 90){
  423. throw new ApiException('时间查询范围请勿超过90天');
  424. }
  425. $whereRaw = '1=1';
  426. if(!empty($params['game_id'])){
  427. $whereRaw .= " AND game_id IN(".implode(',',$params['game_id']).")";
  428. }
  429. if(!empty($params['media_id'])){
  430. $whereRaw .= " AND media_id = ({$params['media_id']})";
  431. }
  432. if(!empty($params['agent_id'])){
  433. $whereRaw .= " AND agent_id IN(".implode(',',$params['agent_id']).")";
  434. }
  435. // 1. 根据注册时间,获取注册付费人数
  436. $payData = Db::connect('db_game_log')->query("
  437. SELECT
  438. SUBSTRING(reg_date,1,10) as dimension, -- 注册日期
  439. COUNT(DISTINCT uid) as pay_num -- 注册付费人数
  440. FROM sdk_order_success
  441. WHERE {$whereRaw} AND reg_date BETWEEN '{$params['reg_date'][0]} 00:00:00' AND '{$params['reg_date'][1]} 23:59:59'
  442. GROUP BY
  443. dimension
  444. ");
  445. $payDataMap = array_column($payData,null,'dimension');
  446. // 2. 计算留存付费的人数
  447. $sqlArr = [];
  448. $medate = date("Y-m-d", strtotime( "+ 60 day", strtotime($params['reg_date'][1])));
  449. $tableNames = ToolLogic::getMonthlyTableNames('sdk_login_log_', $params['reg_date'][0], $medate);
  450. foreach($tableNames as $tableName){
  451. $sqlArr[] = "
  452. SELECT
  453. CONCAT(FROM_UNIXTIME(reg_time, '%Y-%m-%d'), '|', TIMESTAMPDIFF(DAY, FROM_UNIXTIME(reg_time), FROM_UNIXTIME(login_time))) AS dimension, -- 注册日期|留存天数
  454. FROM_UNIXTIME(reg_time, '%Y-%m-%d') AS reg_date, -- 注册日期
  455. TIMESTAMPDIFF(DAY, FROM_UNIXTIME(reg_time), FROM_UNIXTIME(login_time)) AS day_num, -- 留存天数
  456. COUNT(DISTINCT a.user_name) AS remain_num -- 留存人数
  457. FROM {$tableName} AS a
  458. INNER JOIN (
  459. SELECT
  460. DISTINCT user_name
  461. FROM sdk_order_success
  462. WHERE
  463. {$whereRaw} AND reg_date BETWEEN '{$params['reg_date'][0]} 00:00:00' AND '{$params['reg_date'][1]} 23:59:59'
  464. ) AS b ON a.user_name = b.user_name
  465. WHERE
  466. {$whereRaw} AND reg_time BETWEEN ".strtotime($params['reg_date'][0]." 00:00:00")." AND ".strtotime($params['reg_date'][1]." 23:59:59")."
  467. GROUP BY dimension
  468. ";
  469. }
  470. $sql = implode(" UNION ALL ", $sqlArr);
  471. $remainData = Db::connect('db_game_log')->query($sql);
  472. $remainData = $remainData ? array_column($remainData, null, "dimension") : [];
  473. $regDateRange = ToolLogic::getDatesBetween($params['reg_date'][0],$params['reg_date'][1]);
  474. $remainRange = [];
  475. for ($i=2; $i<=30; $i++){
  476. $remainRange[] = $i;
  477. }
  478. $remainRange = array_merge($remainRange, [35,40,45,50,55,60]);
  479. $data = [];
  480. foreach ($regDateRange as $regDate){
  481. $row['reg_date'] = $regDate;
  482. $row['reg_pay_num'] = $payDataMap[$regDate]['pay_num'] ?? 0;
  483. foreach ($remainRange as $remainNum){
  484. $dimension = $regDate . "|" . ($remainNum-1);
  485. $row['remain_' . $remainNum] = $remainData[$dimension]['remain_num'] ?? 0;
  486. }
  487. $data[] = $row;
  488. }
  489. // 合计
  490. $totalRow = [
  491. 'reg_date' => '合计',
  492. ];
  493. // 计算合计
  494. if($data) foreach ($data as $item){
  495. $totalRow['reg_pay_num'] = $totalRow['reg_pay_num'] ?? 0;
  496. $totalRow['reg_pay_num'] += $item['reg_pay_num'];
  497. foreach ($remainRange as $remainNum){
  498. $key = 'remain_'.$remainNum;
  499. $totalRow[$key] = $totalRow[$key] ?? 0;
  500. $totalRow[$key] += $item[$key];
  501. }
  502. }
  503. // 计算比率
  504. if ($params['show_type'] == 'rate') {
  505. if($data) foreach ($remainRange as $remainNum) {
  506. $key = 'remain_' . $remainNum;
  507. $totalRow[$key] = ToolLogic::getPercent($totalRow[$key], $totalRow['reg_pay_num']);
  508. foreach ($data as &$val) {
  509. $val[$key] = ToolLogic::getPercent($val[$key], $val['reg_pay_num']);
  510. }
  511. }
  512. }
  513. return [
  514. 'data' => $data,
  515. 'totalRow' => $totalRow
  516. ];
  517. }
  518. // 生成基础日统计表的联合查询列表
  519. public function generateYearUnionList($namePrefix, $regDate,$whereSql='',$field='*',$group=null){
  520. $tableNames = ToolLogic::getYearlyTableNames($namePrefix, $regDate[0],$regDate[1]);
  521. $sqlParts = [];
  522. foreach ($tableNames as $tableName){
  523. $sqlParts[] = "SELECT * FROM {$tableName} WHERE 1=1 {$whereSql}";
  524. }
  525. $unionSql = implode(" UNION ALL ", $sqlParts);
  526. $finalSql = "
  527. SELECT {$field} FROM ( {$unionSql} ) AS all_total_day
  528. ";
  529. if (!empty($group)) {
  530. $finalSql .= " GROUP BY {$group}";
  531. }
  532. $baseData = Db::connect('db_data_report')->query($finalSql);
  533. return $baseData;
  534. }
  535. // 生成wheresql
  536. public function generateWhereSql($params){
  537. $whereSql = "";
  538. // 游戏id
  539. if(!empty($params['game_id'])){
  540. if (is_array($params['game_id'])) {
  541. $whereSql .= " AND game_id IN(" . implode(',', $params['game_id']) . ")";
  542. } else {
  543. $whereSql .= " AND game_id = {$params['game_id']}";
  544. }
  545. }
  546. // 媒体id
  547. if(!empty($params['media_id'])){
  548. $whereSql .= " AND media_id = {$params['media_id']}";
  549. }
  550. // 渠道id
  551. if(!empty($params['agent_id'])){
  552. $whereSql .= " AND agent_id = {$params['agent_id']}";
  553. }
  554. // 广告位id
  555. if(!empty($params['site_id'])){
  556. if (is_array($params['site_id'])) {
  557. $whereSql .= " AND site_id IN(" . implode(',', $params['site_id']) . ")";
  558. } else {
  559. $whereSql .= " AND site_id = {$params['site_id']}";
  560. }
  561. }
  562. // 负责人
  563. if(!empty($params['auth_id'])){
  564. if (is_array($params['auth_id'])) {
  565. $whereSql .= " AND auth_id IN(" . implode(',', $params['auth_id']) . ")";
  566. } else {
  567. $whereSql .= " AND auth_id = {$params['auth_id']}";
  568. }
  569. }
  570. // 注册日期
  571. if(!empty($params['reg_date'])??null){
  572. $whereSql .= " AND tdate BETWEEN '{$params['reg_date'][0]}' AND '{$params['reg_date'][1]}'";
  573. }
  574. return $whereSql;
  575. }
  576. }