SyncUserLevels.php 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Models\Level;
  4. use App\Models\User;
  5. use App\Services\BalanceLogService;
  6. use Illuminate\Console\Command;
  7. class SyncUserLevels extends Command
  8. {
  9. protected $signature = 'users:sync-levels {--member= : Only this member_id}';
  10. protected $description = 'Raise users.level to match cumulative recharge (经验); never lowers a level';
  11. public function handle(): int
  12. {
  13. if ($member = $this->option('member')) return $this->syncOne($member);
  14. $changed = 0;
  15. User::query()->select('member_id')->orderBy('id')->chunk(500, function ($users) use (&$changed) {
  16. foreach ($users as $user) {
  17. [$before, $after] = BalanceLogService::syncLevel($user->member_id);
  18. if ($after === $before) continue;
  19. $changed++;
  20. $this->line("{$user->member_id}: {$before} -> {$after}");
  21. }
  22. });
  23. $this->info("updated {$changed} users");
  24. return self::SUCCESS;
  25. }
  26. // 单个用户输出计算依据,便于排查为什么没升级
  27. private function syncOne(string $member): int
  28. {
  29. if (!User::where('member_id', $member)->exists()) {
  30. $this->error("member_id {$member} 不存在(请确认传的是 users.member_id,不是 users.id)");
  31. return self::FAILURE;
  32. }
  33. $total = BalanceLogService::getTotalRecharge($member);
  34. $this->line('计入等级的类型:' . implode('、', BalanceLogService::$levelRechargeTypes));
  35. $this->line("累计充值:{$total},按累计充值计算等级:" . BalanceLogService::calculateLevel($total));
  36. $this->line('等级门槛:' . Level::orderBy('level')->get(['level', 'recharge'])
  37. ->map(fn ($l) => "{$l->level}={$l->recharge}")->implode(', '));
  38. [$before, $after] = BalanceLogService::syncLevel($member);
  39. $this->info("当前等级:{$before} -> {$after}" . ($after === $before ? '(未变化,只升不降)' : ''));
  40. return self::SUCCESS;
  41. }
  42. }