SuperballUpdatePoolAndStats.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Facade\TableName;
  4. use App\Services\SuperballActivityService;
  5. use Carbon\Carbon;
  6. use Illuminate\Console\Command;
  7. use Illuminate\Support\Facades\DB;
  8. /**
  9. * Superball 活跃活动:每分钟刷新奖池与展示统计(pool_amount、total_balls、completed_count)
  10. *
  11. * - pool_amount: 取当日游戏总流水的 1/10(来源:RecordGameRoomDayInfo.TotalBet)
  12. * - total_balls & completed_count: 按时间段做一些随机增长,用于前端展示实时热度
  13. */
  14. class SuperballUpdatePoolAndStats extends Command
  15. {
  16. protected $signature = 'superball:update-pool-stats';
  17. protected $description = 'Superball: update pool_amount (1/10 of total game turnover) and grow total_balls/completed_count every minute';
  18. /** @var SuperballActivityService */
  19. protected $service;
  20. public function __construct(SuperballActivityService $service)
  21. {
  22. parent::__construct();
  23. $this->service = $service;
  24. }
  25. public function handle(): int
  26. {
  27. $today = Carbon::today();
  28. $dateStr = $today->format('Y-m-d');
  29. $dateId = $today->format('Ymd');
  30. try {
  31. // 1. 计算当日总流水(TotalBet)并取 1/10 作为奖池
  32. $roomRow = DB::table('QPRecordDB.dbo.RecordGameRoomDayInfo')
  33. ->where('DateID', $dateId)
  34. ->where('SortID', -1)
  35. ->selectRaw('SUM(TotalBet) AS flowing_water_new')
  36. ->first();
  37. $flowing = $roomRow && isset($roomRow->flowing_water_new)
  38. ? (int)$roomRow->flowing_water_new
  39. : 0;
  40. // 奖池 = 总流水的 1/10(内部单位),向下取整
  41. $poolAmount = (int)floor($flowing / 4);
  42. // 2. 确保当日 superball_daily 记录存在(原子 MERGE,不持长锁)
  43. $this->service->getOrCreateDaily($dateStr);
  44. // 3. 计算本次要增加的 completed_count 和 total_balls
  45. $hour = intval(date('H'));
  46. if ($hour < 2) {
  47. $completedInc = mt_rand(5, 10);
  48. $multipliers = [1, 2, 3, 6];
  49. } else if ($hour <= 10) {
  50. $completedInc = mt_rand(10, 15);
  51. $multipliers = [6, 10];
  52. } else {
  53. $completedInc = mt_rand(15, 20);
  54. $multipliers = [10, 15];
  55. }
  56. // 用昨日注册用户数 / 500 作为系数,重新调整 completedInc
  57. $yesterdayDateId = Carbon::yesterday()->format('Ymd');
  58. $yesterdayRegCount = (int) DB::connection('read')
  59. ->table('QPRecordDB.dbo.RecordPlatformData')
  60. ->where('DateID', $yesterdayDateId)
  61. ->where('Channel', -1)
  62. ->value('RegPeple');
  63. $regFactor = $yesterdayRegCount > 0 ? ($yesterdayRegCount / 500) : 0.1;
  64. $regFactor = max(1, $regFactor);
  65. $completedInc = (int) ($completedInc * $regFactor);
  66. $multiplier = $multipliers[array_rand($multipliers)];
  67. $ballsInc = $completedInc * $multiplier;
  68. // 单条 UPDATE 原子累加,不需要事务包裹
  69. DB::connection('write')->table(TableName::agent() . 'superball_daily')
  70. ->where('pool_date', $dateStr)
  71. ->update([
  72. 'pool_amount' => $poolAmount,
  73. 'completed_count' => DB::raw("completed_count + {$completedInc}"),
  74. 'total_balls' => DB::raw("total_balls + {$ballsInc}"),
  75. 'updated_at' => now()->format('Y-m-d H:i:s'),
  76. ]);
  77. \Log::info("Superball pool ###$completedInc###$ballsInc");
  78. \Log::info("Superball pool stats updated for {$dateStr}, pool_amount={$poolAmount}"."--");
  79. return true;
  80. } catch (\Throwable $e) {
  81. \Log::error('Superball update pool stats failed: ' . $e->getMessage());
  82. \Log::error('Superball update pool stats', [
  83. 'date' => $dateStr,
  84. 'error' => $e->getMessage(),
  85. ]);
  86. return false;
  87. }
  88. }
  89. }