SyncPromotions.php 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Services\PromotionAdminService;
  4. use App\Services\PromotionService;
  5. use App\Services\ActivityRewardService;
  6. use App\Support\SyncCommandLock;
  7. use Illuminate\Console\Command;
  8. use Illuminate\Support\Facades\DB;
  9. use Illuminate\Support\Facades\Schema;
  10. use Illuminate\Support\Facades\Log;
  11. class SyncPromotions extends Command
  12. {
  13. protected $signature = 'promotions:sync';
  14. protected $description = '到期活动自动下架,补记转盘任务次数并解冻满足流水的新活动奖金';
  15. public function handle(PromotionService $service, SyncCommandLock $lock): int
  16. {
  17. $exit = $lock->run('promotions:sync', fn () => $this->synchronize($service));
  18. if ($exit === null) $this->info('活动同步已在运行,跳过本次执行');
  19. return $exit ?? self::SUCCESS;
  20. }
  21. private function synchronize(PromotionService $service): int
  22. {
  23. $errors = 0;
  24. $expired = 0;
  25. try {
  26. if (Schema::hasTable('activity_rewards')) $expired += ActivityRewardService::expire();
  27. } catch (\Throwable $e) { ++$errors; Log::error('activity_reward_expire_failed', ['exception' => $e]); }
  28. if (!Schema::hasTable('promotion_accounts')) {
  29. $this->info('活动同步完成,到期下架:' . $expired . ',失败数:' . $errors);
  30. return $errors ? self::FAILURE : self::SUCCESS;
  31. }
  32. try { $expired += PromotionAdminService::expire(); }
  33. catch (\Throwable $e) { ++$errors; Log::error('promotion_expire_failed', ['exception' => $e]); }
  34. DB::table('promotion_accounts as p')->join('promotion_activities as a', 'a.id', '=', 'p.activity_id')->where('a.type', 9)->where('a.status', 1)
  35. ->where('a.start_time', '<=', now()->timestamp)->where('a.end_time', '>=', now()->timestamp)->select('p.*')->orderBy('p.id')
  36. ->chunkById(100, function ($rows) use ($service, &$errors) {
  37. foreach ($rows as $row) try { $service->syncAccount($row->activity_id, $row->user_id); }
  38. catch (\Throwable $e) { ++$errors; Log::error('promotion_sync_failed', ['account_id' => $row->id, 'exception' => $e]); }
  39. }, 'p.id', 'id');
  40. foreach (DB::table('promotion_rewards')->where('status', 'locked')->distinct()->pluck('user_id') as $userId) {
  41. try { $service->unlock((int)$userId); } catch (\Throwable $e) { ++$errors; Log::error('promotion_unlock_failed', ['user_id' => $userId, 'exception' => $e]); }
  42. }
  43. $this->info('活动任务和奖金同步完成,到期下架:' . $expired . ',失败数:' . $errors);
  44. return $errors ? self::FAILURE : self::SUCCESS;
  45. }
  46. }