SuperballController.php 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Facade\TableName;
  4. use App\Http\helper\NumConfig;
  5. use App\Services\SuperballActivityService;
  6. use Illuminate\Http\Request;
  7. use Illuminate\Support\Facades\DB;
  8. /**
  9. * Superball 活跃活动后台统计(仅查询,无导出)
  10. * - 每日数据(含真实完成人数、真实球数)
  11. * - 用户任务完成情况
  12. * - 用户奖励领取情况
  13. */
  14. class SuperballController extends BaseController
  15. {
  16. /**
  17. * 每日总体数据(含真实用户完成人数、真实球数)
  18. * GET /admin/superball/daily
  19. */
  20. public function daily(Request $request)
  21. {
  22. // 不需要日期筛选,直接按日期倒序分页
  23. $list = DB::table(TableName::agent() . 'superball_daily')
  24. ->lock('with(nolock)')
  25. ->orderBy('pool_date', 'desc')
  26. ->paginate(30);
  27. $dates = $list->pluck('pool_date')->all();
  28. $realCompleted = [];
  29. $realBalls = [];
  30. if (!empty($dates)) {
  31. $realCompleted = DB::table(TableName::agent() . 'superball_user_task')
  32. ->whereIn('task_date', $dates)
  33. ->where('status', 1)
  34. ->selectRaw('task_date, COUNT(DISTINCT user_id) as cnt')
  35. ->groupBy('task_date')
  36. ->pluck('cnt', 'task_date')
  37. ->all();
  38. $realBalls = DB::table(TableName::agent() . 'superball_user_balls')
  39. ->whereIn('ball_date', $dates)
  40. ->selectRaw('ball_date, COUNT(*) as cnt')
  41. ->groupBy('ball_date')
  42. ->pluck('cnt', 'ball_date')
  43. ->all();
  44. }
  45. foreach ($list as $row) {
  46. $row->real_user_completed_count = (int)($realCompleted[$row->pool_date] ?? 0);
  47. $row->real_total_balls = (int)($realBalls[$row->pool_date] ?? 0);
  48. $row->pool_amount_display = number_float($row->pool_amount / NumConfig::NUM_VALUE);
  49. $totalBalls = (int)($row->total_balls ?? 0);
  50. $row->base_reward_per_ball_display = $totalBalls > 0
  51. ? number_float($row->pool_amount / NumConfig::NUM_VALUE / $totalBalls)
  52. : '0.00';
  53. // 用户中奖球总数:直接使用 superball_daily.lucky_count 字段
  54. $row->winning_balls_count = (int)($row->lucky_count ?? 0);
  55. // 幸运奖励合计 = 今日中奖球数量 * 每个中奖球奖励(注意是活动配置的中奖奖励,不是基础奖励)
  56. $perLuckyDisplay = SuperballActivityService::LUCKY_REWARD_PER_BALL; // 已是展示单位
  57. if ($row->winning_balls_count > 0 && $perLuckyDisplay > 0) {
  58. $row->total_lucky_reward_display = number_format(
  59. $perLuckyDisplay * $row->winning_balls_count,
  60. 2,
  61. '.',
  62. ''
  63. );
  64. } else {
  65. $row->total_lucky_reward_display = '0.00';
  66. }
  67. }
  68. return view('admin.superball.daily', compact('list'));
  69. }
  70. /**
  71. * 用户任务完成情况(含用户系数、球号码与数量、预计奖励,按更新时间逆序)
  72. * GET /admin/superball/user-tasks
  73. */
  74. public function userTasks(Request $request)
  75. {
  76. $date = $request->input('date');
  77. // 前端输入的是 AccountsInfo 的 GameID,这里按 GameID 反查出 UserID 过滤
  78. $userId = trim((string)$request->input('user_id', ''));
  79. $tier = strtoupper(trim((string)$request->input('tier', '')));
  80. $status = $request->input('status', '');
  81. $query = DB::table(TableName::agent() . 'superball_user_task as t')
  82. ->leftJoin('QPAccountsDB.dbo.AccountsInfo as a', 't.user_id', '=', 'a.UserID')
  83. ->leftJoin(TableName::agent() . 'superball_user_multiplier as m', 't.user_id', '=', 'm.user_id')
  84. ->leftJoin(TableName::agent() . 'superball_tier_config as c', 't.tier', '=', 'c.tier')
  85. ->leftJoin(TableName::agent() . 'superball_daily as d', 't.task_date', '=', 'd.pool_date')
  86. ->selectRaw('t.*, a.GameID as game_id, m.multiplier, c.ball_count as tier_ball_count, d.pool_amount, d.total_balls as daily_total_balls');
  87. if ($date) {
  88. $query->where('t.task_date', $date);
  89. }
  90. if ($userId !== '') {
  91. $query->where('a.GameID', $userId);
  92. }
  93. if ($tier && in_array($tier, ['A', 'B', 'C', 'D', 'E'], true)) {
  94. $query->where('t.tier', $tier);
  95. }
  96. // 仅当明确选择 未领球(0) 或 已领球(1) 时才按状态筛选,避免空值被当成 0
  97. if ($status !== '' && $status !== null && in_array((string)$status, ['0', '1'], true)) {
  98. $query->where('t.status', (int)$status);
  99. }
  100. $query->orderBy('t.updated_at', 'desc');
  101. $list = $query->paginate(20);
  102. $userIds = $list->pluck('user_id')->unique()->values()->all();
  103. $ballsByKey = [];
  104. $taskDates = $list->pluck('task_date')->unique()->values()->all();
  105. if (!empty($userIds) && !empty($taskDates)) {
  106. $balls = DB::table(TableName::agent() . 'superball_user_balls')
  107. ->whereIn('user_id', $userIds)
  108. ->whereIn('ball_date', $taskDates)
  109. ->orderBy('user_id')->orderBy('ball_index')
  110. ->get();
  111. foreach ($balls as $b) {
  112. $k = $b->user_id . '_' . $b->ball_date;
  113. if (!isset($ballsByKey[$k])) {
  114. $ballsByKey[$k] = ['numbers' => [], 'count' => 0];
  115. }
  116. $ballsByKey[$k]['numbers'][] = (int)$b->number;
  117. $ballsByKey[$k]['count']++;
  118. }
  119. }
  120. foreach ($list as $row) {
  121. $row->user_multiplier = $row->multiplier !== null ? (float)$row->multiplier : 1.0;
  122. $k = $row->user_id . '_' . $row->task_date;
  123. $ballInfo = $ballsByKey[$k] ?? ['numbers' => [], 'count' => 0];
  124. $row->ball_numbers_text = implode(',', $ballInfo['numbers']);
  125. $row->ball_count_actual = $ballInfo['count'];
  126. $ballCount = $ballInfo['count'] > 0 ? $ballInfo['count'] : (int)($row->tier_ball_count ?? 0);
  127. $dailyTotal = (int)($row->daily_total_balls ?? 0);
  128. if ($dailyTotal > 0 && $row->pool_amount !== null) {
  129. $basePerBall = (int)$row->pool_amount / $dailyTotal;
  130. $row->estimated_reward_display = number_float(($basePerBall * $ballCount * $row->user_multiplier) / NumConfig::NUM_VALUE);
  131. } else {
  132. $row->estimated_reward_display = '0.00';
  133. }
  134. }
  135. return view('admin.superball.user_tasks', compact('list', 'date', 'userId', 'tier', 'status'));
  136. }
  137. /**
  138. * 用户奖励领取情况
  139. * GET /admin/superball/prizes
  140. */
  141. public function prizes(Request $request)
  142. {
  143. $date = $request->input('date');
  144. $userId = (int)$request->input('user_id', 0);
  145. $query = DB::table(TableName::agent() . 'superball_prize_log as p')
  146. ->leftJoin('QPAccountsDB.dbo.AccountsInfo as a', 'p.user_id', '=', 'a.UserID')
  147. ->selectRaw('p.*, a.GameID, a.NickName')
  148. ->orderBy('p.settle_date', 'desc')
  149. ->orderBy('p.user_id');
  150. if ($date) {
  151. $query->where('p.settle_date', $date);
  152. }
  153. if ($userId > 0) {
  154. $query->where('p.user_id', $userId);
  155. }
  156. $list = $query->paginate(50);
  157. foreach ($list as $row) {
  158. $row->total_amount_display = number_float($row->total_amount / NumConfig::NUM_VALUE);
  159. $row->base_amount_display = number_float($row->base_amount / NumConfig::NUM_VALUE);
  160. $row->lucky_amount_display = number_float($row->lucky_amount / NumConfig::NUM_VALUE);
  161. }
  162. return view('admin.superball.prizes', compact('list', 'date', 'userId'));
  163. }
  164. }