Retaine.php 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. <?php
  2. /**
  3. * 充值记录管理控制器
  4. *
  5. */
  6. namespace app\admin\controller;
  7. use app\common\library\MakeReportGo;
  8. use think\Db;
  9. use app\common\library\MakeReport;
  10. use GuzzleHttp\Client;
  11. use GuzzleHttp\Exception\GuzzleException;
  12. use think\Model;
  13. class Retaine extends Admin
  14. {
  15. public function retaineGame()
  16. {
  17. $tmpGameList = model('Common/Game')->getAllByCondition('name,id', ['cooperation_status' => 1], "id desc", "all");
  18. $gameList = array();
  19. foreach ($tmpGameList as $game) {
  20. $gameList[$game['id']] = $game;
  21. }
  22. $this->assign('gameArr', $tmpGameList);
  23. $this->assign('game_list', $gameList);
  24. list($list, $total) = $this->retaineGameList(request()->param(), 1);
  25. $this->assign('total', $total);
  26. $this->assign('list', $list);
  27. $this->assign('page', $list->render());
  28. return $this->fetch();
  29. }
  30. public function retaineGameChannel()
  31. {
  32. $tmpGameList = model('Common/Game')->getAllByCondition('name,id', ['cooperation_status' => 1]);
  33. $gameList = array();
  34. foreach ($tmpGameList as $game) {
  35. $gameList[$game['id']] = $game;
  36. }
  37. $level = input('level', 0);
  38. $business = model('common/Business')->getChannelIds(session('ADMIN_ID'), $level);
  39. $channelWhere = [];
  40. if ($business != -1) {
  41. if ($business) {
  42. $channelWhere['id'] = ['in', $business];
  43. } else {
  44. $channelWhere['id'] = -1;
  45. }
  46. }
  47. $channel = model('common/Channel')->where(['level' => $level])->where($channelWhere)->field('id,name')->order('id desc')->select();
  48. $channelC = model('common/Channel')->field('id,name')->order('id desc')->select();
  49. foreach ($channelC as $v) {
  50. $channelList[$v['id']] = $v;
  51. }
  52. $this->assign('level', $level);
  53. $this->assign('channel', $channel);
  54. $this->assign('channelList', $channelList);
  55. $this->assign('gameArr', $tmpGameList);
  56. $this->assign('game_list', $gameList);
  57. list($list, $total) = $this->retaineGameList(request()->param(), 2);
  58. $this->assign('total', $total);
  59. $this->assign('list', $list);
  60. $this->assign('page', $list->render());
  61. return $this->fetch();
  62. }
  63. public function retaineGameChannelSummary()
  64. {
  65. $tmpGameList = model('Common/Game')->getAllByCondition('name,id', ['cooperation_status' => 1]);
  66. $gameList = array();
  67. foreach ($tmpGameList as $game) {
  68. $gameList[$game['id']] = $game;
  69. }
  70. $level = input('level', 0);
  71. $business = model('common/Business')->getChannelIds(session('ADMIN_ID'), $level);
  72. $channelWhere = [];
  73. if ($business != -1) {
  74. if ($business) {
  75. $channelWhere['id'] = ['in', $business];
  76. } else {
  77. $channelWhere['id'] = -1;
  78. }
  79. }
  80. $channel = model('common/Channel')->where(['level' => $level])->where($channelWhere)->field('id,name')->order('id desc')->select();
  81. $channelC = model('common/Channel')->field('id,name')->order('id desc')->select();
  82. foreach ($channelC as $v) {
  83. $channelList[$v['id']] = $v;
  84. }
  85. $this->assign('level', $level);
  86. $this->assign('channel', $channel);
  87. $this->assign('channelList', $channelList);
  88. $this->assign('gameArr', $tmpGameList);
  89. $this->assign('game_list', $gameList);
  90. list($list, $total) = $this->retaineGameList(request()->param(), 2, 'summary');
  91. $this->assign('total', $total);
  92. $this->assign('list', $list);
  93. $this->assign('page', $list->render());
  94. return $this->fetch();
  95. }
  96. private function retaineGameList($data, $type_id, $mode = 'normal')
  97. {
  98. $tmpGameList = model('Common/Game')->getAllByCondition('name,id', ['cooperation_status' => 1], "id desc", "all");
  99. $gameIds = '';
  100. if($tmpGameList){
  101. $gameIds = implode(array_column($tmpGameList, 'id'), ',');
  102. $where['game_id'] = ['in', $gameIds];
  103. }
  104. $where['type_id'] = ['=', $type_id];
  105. if (isset($data['game_id']) && $data['game_id']) {
  106. $where['game_id'] = ['in', $data['game_id']];
  107. }
  108. $dataTime = "";
  109. // 开始时间和结束时间不为空时
  110. if (isset($data['start']) && isset($data['end']) && $data['start'] != '' && $data['end'] != '') {
  111. $where['day'] = [
  112. ['>=', $data['start']],
  113. ['<=', $data['end']],
  114. ];
  115. } //开始时间不为空时
  116. elseif (isset($data['start']) && $data['start'] != '') {
  117. $where['day'] = ['>=', $data['start']];
  118. } //结束时间不为空时
  119. elseif (isset($data['end']) && $data['end'] != '') {
  120. $where['day'] = ['<=', $data['end']];
  121. }
  122. // 默认昨天
  123. if(empty($where['day'])){
  124. $dataTime = date('Y-m-d', strtotime('-1 day'));
  125. $where['day'] = [
  126. ['>=', $dataTime],
  127. ['<=', $dataTime],
  128. ];
  129. }
  130. $this->assign('start', $dataTime);
  131. $this->assign('end', $dataTime);
  132. // 判断是否多日期
  133. $rangeTimeStatus = "";
  134. if(!empty($where['day']) && $mode == 'summary'){
  135. // 从原始数据中获取开始和结束日期
  136. $startDate = isset($data['start']) && $data['start'] != '' ? $data['start'] : '';
  137. $endDate = isset($data['end']) && $data['end'] != '' ? $data['end'] : '';
  138. // 如果前端没有传入日期(采用默认日期范围),则从$where条件中解析
  139. if(($startDate == '' || $endDate == '') && isset($where['day'])){
  140. $dayCondition = $where['day'];
  141. // between 条件:[['>=', start], ['<=', end]]
  142. if(isset($dayCondition[0]) && is_array($dayCondition[0])){
  143. if($startDate == '' && isset($dayCondition[0][1])){
  144. $startDate = $dayCondition[0][1];
  145. }
  146. if($endDate == '' && isset($dayCondition[1][1])){
  147. $endDate = $dayCondition[1][1];
  148. }
  149. } else {
  150. // 单条件:['>=', start] 或 ['<=', end]
  151. if($startDate == '' && isset($dayCondition[0]) && $dayCondition[0] == '>=' && isset($dayCondition[1])){
  152. $startDate = $dayCondition[1];
  153. }
  154. if($endDate == '' && isset($dayCondition[0]) && $dayCondition[0] == '<=' && isset($dayCondition[1])){
  155. $endDate = $dayCondition[1];
  156. }
  157. }
  158. }
  159. if($startDate && $endDate){
  160. // 有开始和结束日期
  161. $dayDiff = (strtotime($endDate) - strtotime($startDate))/(24*3600);
  162. if($dayDiff >= 1){
  163. // 多天:显示日期范围
  164. $rangeTimeStatus = $startDate.' 至 '.$endDate;
  165. } else {
  166. // 单天:显示该日期(开始日期和结束日期相同,或日期差小于1天)
  167. $rangeTimeStatus = $startDate;
  168. }
  169. } elseif($startDate){
  170. // 只有开始日期,使用开始日期
  171. $rangeTimeStatus = $startDate;
  172. } elseif($endDate){
  173. // 只有结束日期,使用结束日期
  174. $rangeTimeStatus = $endDate;
  175. }
  176. }
  177. $level = input('level', 0);
  178. $business = model('common/Business')->getChannelIds(session('ADMIN_ID'), $level);
  179. // $type_id = 2, $business = -1, $level = 0
  180. if ($type_id == 2 && $level != 3) {
  181. if ($level == 0) {
  182. if ($business != -1) {
  183. if ($business && $business != -2) {
  184. if (isset($data['channel_id']) && $data['channel_id']) {
  185. if (in_array($data['channel_id'], $business)) {
  186. $where['s_channel_id'] = ['in', $data['channel_id']];
  187. } else {
  188. $where['s_channel_id'] = ['in',[-1]];
  189. }
  190. } else {
  191. $where['s_channel_id'] = ['in', $business];
  192. }
  193. } else {
  194. $where['s_channel_id'] = ['in',[-1]];
  195. }
  196. } else {
  197. if (isset($data['channel_id']) && $data['channel_id']) {
  198. $where['s_channel_id'] = ['in', $data['channel_id']];
  199. }
  200. }
  201. $field = 's_channel_id as channel_id';
  202. $group = 's_channel_id';
  203. } else if ($level == 1) {
  204. // if (isset($data['channel_id']) && $data['channel_id']) {
  205. // $where['b_channel_id'] = ['in', $data['channel_id']];
  206. // }
  207. if ($business != -1) {
  208. if ($business && $business != -2) {
  209. if (isset($data['channel_id']) && $data['channel_id']) {
  210. if (in_array($data['channel_id'], $business)) {
  211. $where['b_channel_id'] = ['in', $data['channel_id']];
  212. } else {
  213. $where['b_channel_id'] = ['in',[-1]];
  214. }
  215. } else {
  216. $where['b_channel_id'] = ['in', $business];
  217. }
  218. } else {
  219. $where['b_channel_id'] = ['in',[-1]];
  220. }
  221. } else {
  222. if (isset($data['channel_id']) && $data['channel_id']) {
  223. $where['b_channel_id'] = ['in', $data['channel_id']];
  224. }
  225. }
  226. $field = 'b_channel_id as channel_id';
  227. $group = 'b_channel_id';
  228. } else if ($level == 2) {
  229. if ($business != -1) {
  230. if ($business && $business != -2) {
  231. if (isset($data['channel_id']) && $data['channel_id']) {
  232. if (in_array($data['channel_id'], $business)) {
  233. $where['bz_channel_id'] = ['in', $data['channel_id']];
  234. } else {
  235. $where['bz_channel_id'] = ['in',[-1]];
  236. }
  237. } else {
  238. $where['bz_channel_id'] = ['in', $business];
  239. }
  240. } else {
  241. $where['bz_channel_id'] = ['in',[-1]];
  242. }
  243. } else {
  244. if (isset($data['channel_id']) && $data['channel_id']) {
  245. $where['bz_channel_id'] = ['in', $data['channel_id']];
  246. }
  247. }
  248. if (!(isset($data['channel_id']) && $data['channel_id'])) {
  249. $where['bz_channel_id'] = ['>', 0];
  250. }
  251. $field = 'bz_channel_id as channel_id';
  252. $group = 'bz_channel_id';
  253. }
  254. if (request()->isAjax()) {
  255. // 根据mode决定group和order
  256. $groupForExport = $group . ',game_id,day';
  257. $orderForExport = 'day desc, reg_num desc, game_id desc';
  258. $dayField = ',day';
  259. if($mode == 'summary' && $rangeTimeStatus){
  260. $groupForExport = $group . ',game_id';
  261. $orderForExport = 'reg_num desc, game_id desc';
  262. // summary模式下,day字段使用空字符串,实际显示由Go代码根据RangeTimeStatus处理
  263. $dayField = ",'".$rangeTimeStatus."' as day";
  264. }
  265. $field = "channel_id"; // TODO:没找到具体问题,因为上边的 $field 看不懂用来干啥的,导致渠道数据下载时候下载为空;这里先用固定方式使用;
  266. $field = 'type_id' . $dayField . ',game_id,bz_channel_id,b_channel_id,s_channel_id,sum(reg_num) as reg_num,sum(role_num) as role_num,sum(act_num) as act_num,sum(recharge_num) as recharge_num,sum(pay_num) as pay_num,sum(one_stay) as one_stay,sum(three_stay) as three_stay,sum(four_stay) as four_stay,sum(five_stay) as five_stay,sum(six_stay) as six_stay,sum(seven_stay) as seven_stay,sum(fifteen_stay) as fifteen_stay,sum(thirty_stay) as thirty_stay, ' . $field;
  267. if($mode == 'summary'){
  268. $field .= " ,reg_total,new_act_num,new_pay_num,new_recharge_num";
  269. }else{
  270. $field .= " ,three_stay_rate,four_stay_rate,five_stay_rate,six_stay_rate,seven_stay_rate,fifteen_stay_rate,thirty_stay_rate,reg_total";
  271. }
  272. $sql = model('common/RetaineGame')->field($field)->where($where)->group($groupForExport)->order($orderForExport)->fetchSql(true)->select();
  273. // $sql = model('common/RetaineGame')->field('type_id' . $dayField . ',game_id,bz_channel_id,b_channel_id,s_channel_id,sum(reg_num) as reg_num,sum(role_num) as role_num,sum(act_num) as act_num,sum(recharge_num) as recharge_num,sum(pay_num) as pay_num,sum(one_stay) as one_stay,sum(three_stay) as three_stay,sum(four_stay) as four_stay,sum(five_stay) as five_stay,sum(six_stay) as six_stay,sum(seven_stay) as seven_stay,sum(fifteen_stay) as fifteen_stay,sum(thirty_stay) as thirty_stay' . $field)->where($where)->group($groupForExport)->order($orderForExport)->fetchSql(true)->select();
  274. $extendParams = ['Level' => $level, 'TypeId' => $type_id, 'Mode' => $mode];
  275. if($mode == 'summary' && $rangeTimeStatus){
  276. $extendParams['RangeTimeStatus'] = $rangeTimeStatus;
  277. }
  278. if ((new MakeReportGo())->addTask('retaineGame', $sql, session_id(), $extendParams)) {
  279. $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等');
  280. } else {
  281. $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!');
  282. }
  283. }
  284. $total = model('common/RetaineGame')->where($where)->field('sum(reg_num) as reg_num,sum(role_num) as role_num,sum(recharge_num) as recharge_num,sum(act_num) as act_num,sum(reg_total) as reg_total')->find();
  285. $groupNew = $group . ',game_id,day';
  286. if($mode == 'summary'){
  287. $groupNew = $group . ',game_id';
  288. }
  289. // dump($groupNew);
  290. // ->field($filed)
  291. $sql = model('common/RetaineGame')->where($where)->group($groupNew)->where($where)->buildSql();
  292. // summary模式下,排序去掉day desc
  293. $orderBy = 'day desc, reg_num desc, game_id desc';
  294. if($mode == 'summary'){
  295. $orderBy = 'reg_num desc, game_id desc';
  296. }
  297. $list = Db::table($sql . ' a')->order($orderBy)->paginate(30, false, ['query' => input('get.')])->each(function ($item, $key) use ($mode, $rangeTimeStatus) {
  298. if($rangeTimeStatus && $mode == 'summary'){
  299. $item['day'] = $rangeTimeStatus;
  300. }
  301. $item['rate'] = $item['act_num'] > 0 ? priceFormat(100 * $item['pay_num'] / $item['act_num']) : '0.00'; // 付费率 = 付费人数/活跃人数
  302. $item['arpu'] = $item['act_num'] > 0 ? priceFormat($item['recharge_num'] / $item['act_num']) : '0.00'; // arpu = 充值金额/活跃玩家
  303. $item['arppu'] = $item['pay_num'] > 0 ? priceFormat($item['recharge_num'] / $item['pay_num']) : '0.00'; // arppu = 充值金额/付费人数
  304. if($mode == 'normal'){
  305. $item['one_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['one_stay'] / $item['reg_num']) : '0.00'; //次留
  306. $item['three_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['three_stay'] / $item['reg_num']) : '0.00'; //三留
  307. $item['four_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['four_stay'] / $item['reg_num']) : '0.00'; //四留
  308. $item['five_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['five_stay'] / $item['reg_num']) : '0.00'; //五留
  309. $item['six_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['six_stay'] / $item['reg_num']) : '0.00'; //六留
  310. $item['seven_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['seven_stay'] / $item['reg_num']) : '0.00'; //七留
  311. $item['fifteen_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['fifteen_stay'] / $item['reg_num']) : '0.00'; //十五留
  312. $item['thirty_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['thirty_stay'] / $item['reg_num']) : '0.00'; //三十留
  313. }else{
  314. $item['old_act_num'] = $item['old_pay_num'] = $item['old_recharge_num'] = 0;
  315. if($item['act_num'] > 0 & ($item['act_num'] - $item['new_act_num']) > 0){
  316. $item['old_act_num'] = $item['act_num'] - $item['new_act_num']; // 老活跃玩家
  317. }
  318. if($item['pay_num'] > 0 & ($item['pay_num'] - $item['new_pay_num']) > 0){
  319. $item['old_pay_num'] = $item['pay_num'] - $item['new_pay_num']; // 老付费玩家
  320. }
  321. if($item['recharge_num'] > 0 & ($item['recharge_num'] - $item['new_recharge_num']) > 0){
  322. $item['old_recharge_num'] = sprintf("%.2f", ($item['recharge_num'] - $item['new_recharge_num'])); // 老玩家付费金额
  323. }
  324. }
  325. return $item;
  326. });
  327. } else {
  328. if ($type_id == 2 && $level = 3) {
  329. if ($business != -1) {
  330. if ($business && $business != -2) {
  331. if (isset($data['channel_id']) && $data['channel_id']) {
  332. if (in_array($data['channel_id'], $business)) {
  333. $where['channel_id'] = ['in', $data['channel_id']];
  334. } else {
  335. $where['channel_id'] = ['in',[-1]];
  336. }
  337. } else {
  338. $where['channel_id'] = ['in', $business];
  339. }
  340. } else {
  341. $where['channel_id'] = ['in',[-1]];
  342. }
  343. } else {
  344. if (isset($data['channel_id']) && $data['channel_id']) {
  345. $where['channel_id'] = ['in', $data['channel_id']];
  346. }
  347. }
  348. }
  349. if (request()->isAjax()) {
  350. // 根据mode决定group和order
  351. $field = '*';
  352. if($mode == 'summary' && $rangeTimeStatus){
  353. // summary模式下,day字段使用空字符串,实际显示由Go代码根据RangeTimeStatus处理
  354. $field = "*,'{$rangeTimeStatus}' as day";
  355. }
  356. $sql = model('common/RetaineGame')->where($where)->field($field)->order('day desc, reg_num desc, game_id desc')->fetchSql(true)->select();
  357. // dump($sql);
  358. if ((new MakeReportGo())->addTask('retaineGame', $sql, session_id(), ['Level' => $level, 'TypeId' => $type_id, 'Mode' => $mode])) {
  359. $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等');
  360. } else {
  361. $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!');
  362. }
  363. }
  364. $total = model('common/RetaineGame')->where($where)->field('sum(reg_num) as reg_num,sum(role_num) as role_num,sum(recharge_num) as recharge_num,sum(act_num) as act_num,sum(reg_total) as reg_total')->find();
  365. $list = model('common/RetaineGame')->where($where)
  366. ->order('day desc, reg_num desc, game_id desc')
  367. // ->order('reg_num desc')
  368. ->paginate(20, false, ['query' => input('get.')])
  369. ->each(function ($item, $key) use ($mode, $rangeTimeStatus) {
  370. if($rangeTimeStatus && $mode == 'summary'){
  371. $item['day'] = $rangeTimeStatus;
  372. }
  373. $item['arpu'] = $item['act_num'] > 0 ? priceFormat($item['recharge_num'] / $item['act_num']) : '0.00'; // 充值金额/活跃玩家
  374. $item['arppu'] = $item['pay_num'] > 0 ? priceFormat($item['recharge_num'] / $item['pay_num']) : '0.00'; // 充值金额/付费人数
  375. if($mode == 'normal'){
  376. $item['rate'] = $item['act_num'] > 0 ? priceFormat(100 * $item['pay_num'] / $item['act_num']) : '0.00'; // 付费率 = 付费人数/活跃人数
  377. $item['one_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['one_stay'] / $item['reg_num']) : '0.00'; //次留
  378. $item['three_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['three_stay'] / $item['reg_num']) : '0.00'; //三留
  379. $item['four_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['four_stay'] / $item['reg_num']) : '0.00'; //四留
  380. $item['five_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['five_stay'] / $item['reg_num']) : '0.00'; //五留
  381. $item['six_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['six_stay'] / $item['reg_num']) : '0.00'; //六留
  382. $item['seven_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['seven_stay'] / $item['reg_num']) : '0.00'; //七留
  383. $item['fifteen_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['fifteen_stay'] / $item['reg_num']) : '0.00'; //十五留
  384. $item['thirty_stay_rate'] = $item['reg_num'] > 0 ? priceFormat(100 * $item['thirty_stay'] / $item['reg_num']) : '0.00'; //三十留
  385. }else{
  386. $item['old_act_num'] = $item['old_pay_num'] = $item['old_recharge_num'] = 0;
  387. if($item['act_num'] > 0 && ($item['act_num'] - $item['new_act_num']) > 0){
  388. $item['old_act_num'] = $item['act_num'] - $item['new_act_num']; // 老活跃玩家
  389. }
  390. if($item['pay_num'] > 0 && ($item['pay_num'] - $item['new_pay_num']) > 0){
  391. $item['old_pay_num'] = $item['pay_num'] - $item['new_pay_num']; // 老付费玩家
  392. }
  393. if($item['recharge_num'] > 0 && ($item['recharge_num'] - $item['new_recharge_num']) > 0){
  394. $item['old_recharge_num'] = sprintf("%.2f", ($item['recharge_num'] - $item['new_recharge_num'])); // 老玩家付费金额
  395. }
  396. }
  397. return $item;
  398. });
  399. }
  400. return [$list, $total];
  401. }
  402. public function retaineServer()
  403. {
  404. $tmpGameList = model('Common/Game')->getAllByCondition('name,id', ['cooperation_status' => 1]);
  405. $gameList = array();
  406. foreach ($tmpGameList as $game) {
  407. $gameList[$game['id']] = $game;
  408. }
  409. $servers = model('common/GameServer')->cache('retaineServer:server', 60)->field('serverid,game_id,servername')->select();
  410. $serversList = [];
  411. foreach ($servers as $k => $v) {
  412. $serversList[$v['game_id'] . '_' . $v['serverid']] = $v['servername'];
  413. }
  414. $this->assign('serversList', $serversList);
  415. $this->assign('gameArr', $tmpGameList);
  416. $this->assign('game_list', $gameList);
  417. list($list, $total) = $this->retaineGameServerList(request()->param(), 1);
  418. $this->assign('total', $total);
  419. $this->assign('list', $list);
  420. $this->assign('page', $list->render());
  421. return $this->fetch();
  422. }
  423. public function retaineServerChannel()
  424. {
  425. $tmpGameList = model('Common/Game')->getAllByCondition('name,id', ['cooperation_status' => 1]);
  426. $gameList = array();
  427. foreach ($tmpGameList as $game) {
  428. $gameList[$game['id']] = $game;
  429. }
  430. $level = input('level', 0);
  431. $business = model('common/Business')->getChannelIds(session('ADMIN_ID'), $level);
  432. $channelWhere = [];
  433. if ($business != -1) {
  434. if ($business) {
  435. $channelWhere['id'] = ['in', $business];
  436. } else {
  437. $channelWhere['id'] = ['in',[-1]];
  438. }
  439. }
  440. $channel = model('common/Channel')->where(['level' => $level])->where($channelWhere)->field('id,name')->order('id desc')->select();
  441. $channelC = model('common/Channel')->field('id,name')->order('id desc')->select();
  442. foreach ($channelC as $v) {
  443. $channelList[$v['id']] = $v;
  444. }
  445. $servers = model('common/GameServer')->cache('retaineServer:server', 60)->field('serverid,game_id,servername')->select();
  446. $serversList = [];
  447. foreach ($servers as $k => $v) {
  448. $serversList[$v['game_id'] . '_' . $v['serverid']] = $v['servername'];
  449. }
  450. $this->assign('serversList', $serversList);
  451. $this->assign('level', $level);
  452. $this->assign('channel', $channel);
  453. $this->assign('channelList', $channelList);
  454. $this->assign('gameArr', $tmpGameList);
  455. $this->assign('game_list', $gameList);
  456. list($list, $total) = $this->retaineGameServerList(request()->param(), 2);
  457. $this->assign('total', $total);
  458. $this->assign('list', $list);
  459. $this->assign('page', $list->render());
  460. return $this->fetch();
  461. }
  462. private function retaineGameServerList($data, $type_id)
  463. {
  464. $where['type_id'] = ['=', $type_id];
  465. if (isset($data['server_id']) && $data['server_id']) {
  466. $where['server_id'] = ['in', $data['server_id']];
  467. }
  468. if (isset($data['game_id']) && $data['game_id']) {
  469. $where['game_id'] = ['in', $data['game_id']];
  470. }
  471. //开始时间和结束时间不为空时
  472. if (isset($data['start']) && isset($data['end']) && $data['start'] != '' && $data['end'] != '') {
  473. $where['day'] = [
  474. ['>=', $data['start']],
  475. ['<=', $data['end']],
  476. ];
  477. } //开始时间不为空时
  478. elseif (isset($data['start']) && $data['start'] != '') {
  479. $where['day'] = ['>=', $data['start']];
  480. } //结束时间不为空时
  481. elseif (isset($data['end']) && $data['end'] != '') {
  482. $where['day'] = ['<=', $data['end']];
  483. }
  484. // 默认昨天
  485. if(empty($where['day'])){
  486. $dataTime = date('Y-m-d', strtotime('-1 day'));
  487. $where['day'] = [
  488. ['>=', $dataTime],
  489. ['<=', $dataTime],
  490. ];
  491. $this->assign('start', $dataTime);
  492. $this->assign('end', $dataTime);
  493. }
  494. $level = input('level', 0);
  495. $business = model('common/Business')->getChannelIds(session('ADMIN_ID'), $level);
  496. if ($type_id == 2 && $level != 3) {
  497. if ($level == 0) {
  498. if ($business != -1) {
  499. if ($business && $business != -2) {
  500. if (isset($data['channel_id']) && $data['channel_id']) {
  501. if (in_array($data['channel_id'], $business)) {
  502. $where['s_channel_id'] = ['in', $data['channel_id']];
  503. } else {
  504. $where['s_channel_id'] = ['in',[-1]];
  505. }
  506. } else {
  507. $where['s_channel_id'] = ['in', $business];
  508. }
  509. } else {
  510. $where['s_channel_id'] = ['in',[-1]];
  511. }
  512. } else {
  513. if (isset($data['channel_id']) && $data['channel_id']) {
  514. $where['s_channel_id'] = ['in', $data['channel_id']];
  515. }
  516. }
  517. $field = ',s_channel_id as channel_id';
  518. $group = 's_channel_id';
  519. } else if ($level == 1) {
  520. // if (isset($data['channel_id']) && $data['channel_id']) {
  521. // $where['b_channel_id'] = ['in', $data['channel_id']];
  522. // }
  523. if ($business != -1) {
  524. if ($business && $business != -2) {
  525. if (isset($data['channel_id']) && $data['channel_id']) {
  526. if (in_array($data['channel_id'], $business)) {
  527. $where['b_channel_id'] = ['in', $data['channel_id']];
  528. } else {
  529. $where['b_channel_id'] = ['in',[-1]];
  530. }
  531. } else {
  532. $where['b_channel_id'] = ['in', $business];
  533. }
  534. } else {
  535. $where['b_channel_id'] = ['in',[-1]];
  536. }
  537. } else {
  538. if (isset($data['channel_id']) && $data['channel_id']) {
  539. $where['b_channel_id'] = ['in', $data['channel_id']];
  540. }
  541. }
  542. $field = ',b_channel_id as channel_id';
  543. $group = 'b_channel_id';
  544. } else if ($level == 2) {
  545. if ($business != -1) {
  546. if ($business && $business != -2) {
  547. if (isset($data['channel_id']) && $data['channel_id']) {
  548. if (in_array($data['channel_id'], $business)) {
  549. $where['bz_channel_id'] = ['in', $data['channel_id']];
  550. } else {
  551. $where['bz_channel_id'] = ['in',[-1]];
  552. }
  553. } else {
  554. $where['bz_channel_id'] = ['in', $business];
  555. }
  556. } else {
  557. $where['bz_channel_id'] = ['in',[-1]];
  558. }
  559. } else {
  560. if (isset($data['channel_id']) && $data['channel_id']) {
  561. $where['bz_channel_id'] = ['in', $data['channel_id']];
  562. }
  563. }
  564. if (!(isset($data['channel_id']) && $data['channel_id'])) {
  565. $where['bz_channel_id'] = ['>', 0];
  566. }
  567. $field = ',bz_channel_id as channel_id';
  568. $group = 'bz_channel_id';
  569. }
  570. if (request()->isAjax()) {
  571. $sql = model('common/RetaineServer')->field('type_id,day,game_id,server_id,bz_channel_id,b_channel_id,s_channel_id,sum(reg_num) as reg_num,sum(role_num) as role_num,sum(act_num) as act_num,sum(recharge_num) as recharge_num,sum(pay_num) as pay_num,sum(one_stay) as one_stay,sum(three_stay) as three_stay,sum(four_stay) as four_stay,sum(five_stay) as five_stay,sum(six_stay) as six_stay,sum(seven_stay) as seven_stay,sum(fifteen_stay) as fifteen_stay,sum(thirty_stay) as thirty_stay' . $field)->where($where)->group($group . ',game_id,server_id,day')->orderRaw('day desc,reg_num desc')->fetchSql(true)->select();
  572. if ((new MakeReportGo())->addTask('retaineGameServer', $sql, session_id(), ['Level' => $level, 'TypeId' => $type_id])) {
  573. $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等');
  574. } else {
  575. $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!');
  576. }
  577. }
  578. $total = model('common/RetaineServer')->where($where)->field('sum(reg_num) as reg_num,sum(role_num) as role_num,sum(recharge_num) as recharge_num,sum(act_num) as act_num')->find();
  579. $sql = model('common/RetaineServer')->field('type_id,day,game_id,server_id,bz_channel_id,b_channel_id,s_channel_id,sum(reg_num) as reg_num,sum(role_num) as role_num,sum(act_num) as act_num,sum(recharge_num) as recharge_num,sum(pay_num) as pay_num,sum(one_stay) as one_stay,sum(three_stay) as three_stay,sum(four_stay) as four_stay,sum(five_stay) as five_stay,sum(six_stay) as six_stay,sum(seven_stay) as seven_stay,sum(fifteen_stay) as fifteen_stay,sum(thirty_stay) as thirty_stay' . $field)->where($where)->group($group . ',game_id,server_id,day')->buildSql();
  580. $list = Db::table($sql . ' a')->orderRaw('day desc,reg_num desc')->paginate(20, false, ['query' => input('get.')])->each(function ($item, $key) {
  581. $item['rate'] = $item['act_num'] > 0 ? priceFormat(100 * $item['pay_num'] / $item['act_num']) : '0.00';//付费人数/活跃人数
  582. $item['arpu'] = $item['act_num'] > 0 ? priceFormat($item['recharge_num'] / $item['act_num']) : '0.00';//充值金额/活跃玩家
  583. $item['arppu'] = $item['pay_num'] > 0 ? priceFormat($item['recharge_num'] / $item['pay_num']) : '0.00';// 充值金额/付费人数
  584. $item['one_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['one_stay'] / $item['role_num']) : '0.00'; //次留
  585. $item['three_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['three_stay'] / $item['role_num']) : '0.00'; //三留
  586. $item['four_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['four_stay'] / $item['role_num']) : '0.00'; //四留
  587. $item['five_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['five_stay'] / $item['role_num']) : '0.00'; //五留
  588. $item['six_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['six_stay'] / $item['role_num']) : '0.00'; //六留
  589. $item['seven_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['seven_stay'] / $item['role_num']) : '0.00'; //七留
  590. $item['fifteen_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['fifteen_stay'] / $item['role_num']) : '0.00'; //十五留
  591. $item['thirty_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['thirty_stay'] / $item['role_num']) : '0.00'; //三十留
  592. return $item;
  593. });
  594. } else {
  595. if ($level = 3 && $type_id == 2) {
  596. if ($business != -1) {
  597. if ($business && $business != -2) {
  598. if (isset($data['channel_id']) && $data['channel_id']) {
  599. if (in_array($data['channel_id'], $business)) {
  600. $where['channel_id'] = ['in', $data['channel_id']];
  601. } else {
  602. $where['channel_id'] = ['in',[-1]];
  603. }
  604. } else {
  605. $where['channel_id'] = ['in', $business];
  606. }
  607. } else {
  608. $where['channel_id'] = ['in',[-1]];
  609. }
  610. } else {
  611. if (isset($data['channel_id']) && $data['channel_id']) {
  612. $where['channel_id'] = ['in', $data['channel_id']];
  613. }
  614. }
  615. }
  616. if (request()->isAjax()) {
  617. $sql = model('common/RetaineServer')->where($where)->orderRaw('day desc,reg_num desc')->fetchSql(true)->select();
  618. if ((new MakeReportGo())->addTask('retaineGameServer', $sql, session_id(), ['Level' => $level, 'TypeId' => $type_id])) {
  619. $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等');
  620. } else {
  621. $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!');
  622. }
  623. }
  624. $total = model('common/RetaineServer')->where($where)->field('sum(reg_num) as reg_num,sum(role_num) as role_num,sum(recharge_num) as recharge_num,sum(act_num) as act_num')->find();
  625. $list = model('common/RetaineServer')->where($where)->orderRaw('day desc,reg_num desc')->paginate(20, false, ['query' => input('get.')])->each(function ($item, $key) {
  626. $item['rate'] = $item['act_num'] > 0 ? priceFormat(100 * $item['pay_num'] / $item['act_num']) : '0.00';//付费人数/活跃人数
  627. $item['arpu'] = $item['act_num'] > 0 ? priceFormat($item['recharge_num'] / $item['act_num']) : '0.00';//充值金额/活跃玩家
  628. $item['arppu'] = $item['pay_num'] > 0 ? priceFormat($item['recharge_num'] / $item['pay_num']) : '0.00';// 充值金额/付费人数
  629. $item['one_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['one_stay'] / $item['role_num']) : '0.00'; //次留
  630. $item['three_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['three_stay'] / $item['role_num']) : '0.00'; //三留
  631. $item['four_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['four_stay'] / $item['role_num']) : '0.00'; //四留
  632. $item['five_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['five_stay'] / $item['role_num']) : '0.00'; //五留
  633. $item['six_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['six_stay'] / $item['role_num']) : '0.00'; //六留
  634. $item['seven_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['seven_stay'] / $item['role_num']) : '0.00'; //七留
  635. $item['fifteen_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['fifteen_stay'] / $item['role_num']) : '0.00'; //十五留
  636. $item['thirty_stay_rate'] = $item['role_num'] > 0 ? priceFormat($item['thirty_stay'] / $item['role_num']) : '0.00'; //三十留
  637. return $item;
  638. });
  639. }
  640. return [$list, $total];
  641. }
  642. public function getServer()
  643. {
  644. $games = explode(',', input('game'));
  645. if(in_array(223,$games) || in_array(224,$games)){
  646. $list = model('common/GameServer')
  647. ->where('game_id', 'in', explode(',', input('game')))
  648. ->whereRaw('serverid!=-1')
  649. ->field('servername as name,serverid as id')->group('serverid')->orderRaw('convert(serverid,signed) desc')->select();
  650. }else{
  651. $list = model('common/GameServer')
  652. ->where('game_id', 'in', explode(',', input('game')))
  653. ->whereRaw('serverid!=servername')
  654. ->field('servername as name,serverid as id')->group('serverid')->orderRaw('convert(serverid,signed) desc')->select();
  655. }
  656. $this->jsonResult($list, 1, '成功');
  657. }
  658. public function getChannel()
  659. {
  660. $business = model('common/Business')->getChannelIds(session('ADMIN_ID'), input('level', 0));
  661. $channelWhere = [];
  662. if ($business != -1) {
  663. if ($business) {
  664. $channelWhere['id'] = ['in', $business];
  665. } else {
  666. $channelWhere['id'] = -1;
  667. }
  668. }
  669. $channel = model('common/Channel')->where(['level' => input('level', 0)])->where($channelWhere)->field('id,name')->order('id desc')->select();
  670. $this->jsonResult($channel, 1, '成功');
  671. }
  672. public function retaine()
  673. {
  674. list($list, $total) = $this->retainePlatformList(request()->param(), 1);
  675. $this->assign('total', $total);
  676. $this->assign('list', $list);
  677. $this->assign('page', $list->render());
  678. return $this->fetch();
  679. }
  680. private function retainePlatformList($data, $type_id)
  681. {
  682. $where['type_id'] = ['=', $type_id];
  683. //开始时间和结束时间不为空时
  684. if (isset($data['start']) && isset($data['end']) && $data['start'] != '' && $data['end'] != '') {
  685. $where['day'] = [
  686. ['>=', $data['start']],
  687. ['<=', $data['end']],
  688. ];
  689. } //开始时间不为空时
  690. elseif (isset($data['start']) && $data['start'] != '') {
  691. $where['day'] = ['>=', $data['start']];
  692. } //结束时间不为空时
  693. elseif (isset($data['end']) && $data['end'] != '') {
  694. $where['day'] = ['<=', $data['end']];
  695. }
  696. $level = input('level', 0);
  697. $business = model('common/Business')->getChannelIds(session('ADMIN_ID'), $level);
  698. if ($type_id == 2 && $level != 3) {
  699. if ($level == 0) {
  700. if ($business != -1) {
  701. if ($business && $business != -2) {
  702. if (isset($data['channel_id']) && $data['channel_id']) {
  703. if (in_array($data['channel_id'], $business)) {
  704. $where['s_channel_id'] = ['in', $data['channel_id']];
  705. } else {
  706. $where['s_channel_id'] = ['in',[-1]];
  707. }
  708. } else {
  709. $where['s_channel_id'] = ['in', $business];
  710. }
  711. } else {
  712. $where['s_channel_id'] = ['in',[-1]];
  713. }
  714. } else {
  715. if (isset($data['channel_id']) && $data['channel_id']) {
  716. $where['s_channel_id'] = ['in', $data['channel_id']];
  717. }
  718. }
  719. $field = ',s_channel_id as channel_id';
  720. $group = 's_channel_id';
  721. } else if ($level == 1) {
  722. if ($business != -1) {
  723. if ($business && $business != -2) {
  724. if (isset($data['channel_id']) && $data['channel_id']) {
  725. if (in_array($data['channel_id'], $business)) {
  726. $where['b_channel_id'] = ['in', $data['channel_id']];
  727. } else {
  728. $where['b_channel_id'] = ['in',[-1]];
  729. }
  730. } else {
  731. $where['b_channel_id'] = ['in', $business];
  732. }
  733. } else {
  734. $where['b_channel_id'] = ['in',[-1]];
  735. }
  736. } else {
  737. if (isset($data['channel_id']) && $data['channel_id']) {
  738. $where['b_channel_id'] = ['in', $data['channel_id']];
  739. }
  740. }
  741. $field = ',b_channel_id as channel_id';
  742. $group = 'b_channel_id';
  743. } else if ($level == 2) {
  744. if ($business != -1) {
  745. if ($business && $business != -2) {
  746. if (isset($data['channel_id']) && $data['channel_id']) {
  747. if (in_array($data['channel_id'], $business)) {
  748. $where['bz_channel_id'] = ['in', $data['channel_id']];
  749. } else {
  750. $where['bz_channel_id'] = ['in',[-1]];
  751. }
  752. } else {
  753. $where['bz_channel_id'] = ['in', $business];
  754. }
  755. } else {
  756. $where['bz_channel_id'] = ['in',[-1]];
  757. }
  758. } else {
  759. if (isset($data['channel_id']) && $data['channel_id']) {
  760. $where['bz_channel_id'] = ['in', $data['channel_id']];
  761. }
  762. }
  763. $field = ',bz_channel_id as channel_id';
  764. $group = 'bz_channel_id';
  765. }
  766. if (request()->isAjax()) {
  767. $sql = model('common/Retaine')->field('type_id,day,bz_channel_id,b_channel_id,s_channel_id,sum(reg_num) as reg_num,sum(role_num) as role_num,sum(act_num) as act_num,sum(recharge_num) as recharge_num,sum(pay_num) as pay_num' . $field)->where($where)->group($group)->order('day desc')->fetchSql(true)->select();
  768. if ((new MakeReportGo())->addTask('retaine', $sql, session_id(), ['Level' => $level, 'TypeId' => $type_id])) {
  769. $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等');
  770. } else {
  771. $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!');
  772. }
  773. }
  774. $total = model('common/Retaine')->where($where)->field('sum(reg_num) as reg_num,sum(role_num) as role_num,sum(recharge_num) as recharge_num,sum(act_num) as act_num')->find();
  775. $sql = model('common/Retaine')->field('type_id,day,bz_channel_id,b_channel_id,s_channel_id,sum(reg_num) as reg_num,sum(role_num) as role_num,sum(act_num) as act_num,sum(recharge_num) as recharge_num,sum(pay_num) as pay_num' . $field)->where($where)->group($group . ',day')->where($where)->buildSql();
  776. $list = Db::table($sql . ' a')->order('day desc')->paginate(20, false, ['query' => input('get.')])->each(function ($item, $key) {
  777. $item['rate'] = $item['act_num'] > 0 ? priceFormat(100 * $item['pay_num'] / $item['act_num']) : '0.00';//付费人数/活跃人数
  778. $item['arpu'] = $item['act_num'] > 0 ? priceFormat($item['recharge_num'] / $item['act_num']) : '0.00';//充值金额/活跃玩家
  779. $item['arppu'] = $item['pay_num'] > 0 ? priceFormat($item['recharge_num'] / $item['pay_num']) : '0.00';// 充值金额/付费人数
  780. return $item;
  781. });
  782. } else {
  783. if (request()->isAjax()) {
  784. $sql = model('common/Retaine')->where($where)->order('day desc')->fetchSql(true)->select();
  785. if ((new MakeReportGo())->addTask('retaine', $sql, session_id(), ['Level' => $level, 'TypeId' => $type_id])) {
  786. $this->success('报表生成的任务已经提交, 报表生成完成后,会及时通知您,请耐心稍等');
  787. } else {
  788. $this->error('报表生成任务不可重复提交,如遇到无法导出情况,建议修改查询条件解除当前状态,提交重新生成报表任务!');
  789. }
  790. }
  791. $total = model('common/Retaine')->where($where)->field('sum(reg_num) as reg_num,sum(role_num) as role_num,sum(recharge_num) as recharge_num,sum(act_num) as act_num')->find();
  792. $list = model('common/Retaine')->where($where)->order('day desc')->paginate(20, false, ['query' => input('get.')])->each(function ($item, $key) {
  793. $item['rate'] = $item['act_num'] > 0 ? priceFormat(100 * $item['pay_num'] / $item['act_num']) : '0.00';// 付费人数/活跃人数
  794. $item['arpu'] = $item['act_num'] > 0 ? priceFormat($item['recharge_num'] / $item['act_num']) : '0.00';// 充值金额/活跃玩家
  795. $item['arppu'] = $item['pay_num'] > 0 ? priceFormat($item['recharge_num'] / $item['pay_num']) : '0.00';// 充值金额/付费人数
  796. return $item;
  797. });
  798. }
  799. return [$list, $total];
  800. }
  801. }