SyncPromotions.php 2.2 KB

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