ComplexSummaryComplex.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. <?php
  2. namespace app\admin\controller;
  3. use think\Db;
  4. use app\common\model\ComplexChannelModel;
  5. use app\common\library\MakeReportGo;
  6. /**
  7. * 聚合-渠道数据汇总控制器
  8. */
  9. class ComplexSummaryComplex extends Admin
  10. {
  11. /**
  12. * 渠道数据汇总列表
  13. */
  14. public function index()
  15. {
  16. $tmpGameList = model('Common/Game')->getAllByCondition('name,id', ['cooperation_status' => 1], "id desc", "all");
  17. $gameList = [];
  18. foreach ($tmpGameList as $game) {
  19. $gameList[$game['id']] = $game;
  20. }
  21. $channelList = (new ComplexChannelModel())->getAllByCondition('id,name', ['flag' => 4], 'name asc');
  22. $channelByIdList = [];
  23. foreach ($channelList as $channel) {
  24. $channelByIdList[$channel['id']] = $channel;
  25. }
  26. // 设置默认时间范围(昨天)
  27. $defaultDate = date('Y-m-d', strtotime('-1 day'));
  28. $defaultStart = $defaultDate;
  29. $defaultEnd = $defaultDate;
  30. $this->assign('gameArr', $tmpGameList);
  31. $this->assign('game_list', $gameList);
  32. $this->assign('channel_list', $channelByIdList);
  33. $this->assign('default_start', $defaultStart);
  34. $this->assign('default_end', $defaultEnd);
  35. list($list, $total) = $this->getSummaryList(request()->param());
  36. // 参考Complex.php的方式处理分页数据
  37. // 确保 $list 是分页对象,如果不是则获取总数
  38. $listTotal = is_object($list) && method_exists($list, 'total') ? $list->total() : (is_array($list) ? count($list) : 0);
  39. $listData = is_object($list) && method_exists($list, 'toArray') ? $list->toArray()['data'] : (is_array($list) ? $list : []);
  40. $pageHtml = is_object($list) && method_exists($list, 'render') ? $list->render() : '';
  41. $this->assign('total', $total);
  42. $this->assign('list', $listData);
  43. $this->assign('listTotal', $listTotal); // 传递总数,供视图使用
  44. $this->assign('page', $pageHtml);
  45. return $this->fetch();
  46. }
  47. /**
  48. * 获取汇总列表数据
  49. */
  50. private function getSummaryList($data)
  51. {
  52. $where = [];
  53. $isDateRange = false;
  54. $startDate = '';
  55. $endDate = '';
  56. // 游戏筛选
  57. if (isset($data['game_id']) && $data['game_id']) {
  58. $gameIds = is_array($data['game_id']) ? $data['game_id'] : explode(',', $data['game_id']);
  59. $where['game_id'] = ['in', $gameIds];
  60. }
  61. // 时间筛选
  62. if (isset($data['start']) && isset($data['end']) && $data['start'] != '' && $data['end'] != '') {
  63. $startDate = $data['start'];
  64. $endDate = $data['end'];
  65. // 计算日期差
  66. $startTimestamp = strtotime($startDate);
  67. $endTimestamp = strtotime($endDate);
  68. $daysDiff = ($endTimestamp - $startTimestamp) / 86400;
  69. // 如果日期范围大于1天,需要汇总
  70. if ($daysDiff >= 1) {
  71. $isDateRange = true;
  72. }
  73. $where['day'] = [
  74. ['>=', $data['start']],
  75. ['<=', $data['end']],
  76. ];
  77. } elseif (isset($data['start']) && $data['start'] != '') {
  78. $where['day'] = ['>=', $data['start']];
  79. } elseif (isset($data['end']) && $data['end'] != '') {
  80. $where['day'] = ['<=', $data['end']];
  81. } else {
  82. // 默认昨天
  83. $defaultDate = date('Y-m-d', strtotime('-1 day'));
  84. $startDate = $defaultDate;
  85. $endDate = $defaultDate;
  86. $where['day'] = [
  87. ['>=', $defaultDate],
  88. ['<=', $defaultDate],
  89. ];
  90. if (!isset($data['start'])) {
  91. $data['start'] = $defaultDate;
  92. }
  93. if (!isset($data['end'])) {
  94. $data['end'] = $defaultDate;
  95. }
  96. }
  97. $param = input('get.');
  98. // 如果日期范围大于1天,按游戏ID和渠道ID汇总
  99. if ($isDateRange) {
  100. // 先获取所有汇总数据
  101. $allList = Db::table('cy_complex_summary_complex')
  102. ->where($where)
  103. ->field('game_id, complex_id,
  104. sum(reg_num) as reg_num,
  105. sum(pay_user_num) as pay_user_num,
  106. sum(active_user_num) as active_user_num,
  107. sum(pay_total) as pay_total,
  108. sum(pay_amount_total) as pay_amount_total')
  109. ->group('game_id, complex_id')
  110. ->order('day,reg_num desc')
  111. ->select();
  112. // 转换为数组(统一处理,兼容数组和Collection对象)
  113. $allList = $allList ?: [];
  114. if (!is_array($allList) && method_exists($allList, 'toArray')) {
  115. $allList = $allList->toArray();
  116. }
  117. // 处理汇总数据,设置日期范围
  118. foreach ($allList as &$item) {
  119. $item['day'] = $startDate . ' ~ ' . $endDate;
  120. }
  121. unset($item);
  122. // 手动分页处理
  123. $page = intval(input('get.page', 1));
  124. $page = $page > 0 ? $page : 1;
  125. $limit = 20;
  126. $totalCount = count($allList);
  127. $offset = ($page - 1) * $limit;
  128. $listData = array_slice($allList, $offset, $limit);
  129. // 创建分页对象,参考Complex.php的方式
  130. $collection = new \think\Collection($listData);
  131. $list = \think\paginator\driver\Bootstrap::make($collection, $limit, $page, $totalCount, false, [
  132. 'var_page' => 'page',
  133. 'path' => request()->url(),
  134. 'query' => $param,
  135. ]);
  136. } else {
  137. // 查询列表(原有逻辑)
  138. $list = Db::table('cy_complex_summary_complex')
  139. ->where($where)
  140. ->order('day,reg_num desc')
  141. ->paginate(20, false, ['query' => $param]);
  142. }
  143. // 计算汇总
  144. $total = Db::table('cy_complex_summary_complex')
  145. ->where($where)
  146. ->field('sum(reg_num) as reg_num, sum(pay_user_num) as pay_user_num,
  147. sum(active_user_num) as active_user_num, sum(pay_total) as pay_total, sum(pay_amount_total) as pay_amount_total')
  148. ->find();
  149. return [$list, $total ?: ['reg_num' => 0, 'pay_user_num' => 0, 'active_user_num' => 0, 'pay_total' => 0, 'pay_amount_total' => 0]];
  150. }
  151. /**
  152. * 导出数据
  153. */
  154. public function export()
  155. {
  156. if (request()->isPost()) {
  157. $data = input('post.');
  158. $where = [];
  159. $isDateRange = false;
  160. $startDate = '';
  161. $endDate = '';
  162. // 游戏筛选
  163. if (isset($data['game_id']) && $data['game_id']) {
  164. $gameIds = is_array($data['game_id']) ? $data['game_id'] : explode(',', $data['game_id']);
  165. $where['game_id'] = ['in', $gameIds];
  166. }
  167. // 时间筛选
  168. if (isset($data['start']) && isset($data['end']) && $data['start'] != '' && $data['end'] != '') {
  169. $startDate = $data['start'];
  170. $endDate = $data['end'];
  171. // 计算日期差
  172. $startTimestamp = strtotime($startDate);
  173. $endTimestamp = strtotime($endDate);
  174. $daysDiff = ($endTimestamp - $startTimestamp) / 86400;
  175. // 如果日期范围大于1天,需要汇总
  176. if ($daysDiff >= 1) {
  177. $isDateRange = true;
  178. }
  179. $where['day'] = [
  180. ['>=', $data['start']],
  181. ['<=', $data['end']],
  182. ];
  183. } elseif (isset($data['start']) && $data['start'] != '') {
  184. $where['day'] = ['>=', $data['start']];
  185. } elseif (isset($data['end']) && $data['end'] != '') {
  186. $where['day'] = ['<=', $data['end']];
  187. } else {
  188. // 默认昨天
  189. $defaultDate = date('Y-m-d', strtotime('-1 day'));
  190. $startDate = $defaultDate;
  191. $endDate = $defaultDate;
  192. $where['day'] = [
  193. ['>=', $defaultDate],
  194. ['<=', $defaultDate],
  195. ];
  196. }
  197. // 构建查询SQL
  198. $query = Db::table('cy_complex_summary_complex');
  199. // 如果日期范围大于1天,按游戏ID和渠道ID汇总
  200. if ($isDateRange) {
  201. $sql = $query
  202. ->where($where)
  203. ->field('game_id, complex_id, day,
  204. sum(reg_num) as reg_num,
  205. sum(pay_user_num) as pay_user_num,
  206. sum(active_user_num) as active_user_num,
  207. sum(pay_total) as pay_total,
  208. sum(pay_amount_total) as pay_amount_total')
  209. ->group('game_id, complex_id')
  210. ->order('day,reg_num desc')
  211. ->fetchSql(true)
  212. ->select();
  213. } else {
  214. $sql = $query
  215. ->where($where)
  216. ->field('game_id, complex_id, day, reg_num, pay_user_num, active_user_num, pay_total, pay_amount_total')
  217. ->order('day,reg_num desc')
  218. ->fetchSql(true)
  219. ->select();
  220. }
  221. // 扩展参数,用于Go脚本处理
  222. $extend = [
  223. 'is_date_range' => $isDateRange,
  224. 'start_date' => $startDate,
  225. 'end_date' => $endDate,
  226. 'task_type' => 'complexSummaryComplexExport',
  227. 'file_name' => "渠道-渠道数据汇总_%s.csv",
  228. 'headers' => [
  229. ['field' => 'day', 'title' => '日期'],
  230. ['field' => 'game_id', 'title' => '游戏名称'],
  231. ['field' => 'complex_id', 'title' => '渠道名称'],
  232. ['field' => 'reg_num', 'title' => '新增玩家'],
  233. ['field' => 'pay_user_num', 'title' => '新增付费玩家'],
  234. ['field' => 'active_user_num','title' => '活跃玩家'],
  235. ['field' => 'pay_total', 'title' => '订单金额'],
  236. ['field' => 'pay_amount_total', 'title' => '实付金额'],
  237. ],
  238. // 字段处理
  239. 'handle_fields' => [
  240. [
  241. 'field' => 'game_id',
  242. 'handler' => 'mapGameName',
  243. 'target_field' => 'game_name',
  244. 'extra' => [
  245. 'table_name' => 'cy_game',
  246. 'field_key' => 'name',
  247. 'where_key' => 'id',
  248. ],
  249. ],
  250. [
  251. 'field' => 'complex_id',
  252. 'handler' => 'mapComplexName',
  253. 'target_field' => 'complex_name',
  254. 'extra' => [
  255. 'table_name' => 'nw_complex_channel',
  256. 'field_key' => 'name',
  257. 'where_key' => 'id',
  258. ],
  259. ],
  260. ],
  261. ];
  262. if ((new MakeReportGo())->addTask('admin.complexSummary', $sql, session_id(), $extend)) {
  263. $this->jsonResult('', 1, '报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等');
  264. } else {
  265. $this->jsonResult('', 0, '报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!');
  266. }
  267. }
  268. }
  269. }