SystemNotificationSendJob.php 2.18 KB
<?php

namespace App\Jobs;

use App\Enums\NotificationStatusEnum;
use App\Models\Notification;
use App\Models\NotificationUser;
use Bus;
use Illuminate\Bus\Batch;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;

class SystemNotificationSendJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    /**
     * @var \App\Models\Notification
     */
    public Notification $notification;

    public function middleware(): array
    {
        return [new WithoutOverlapping($this->notification->getKey())];
    }
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Notification $notification)
    {
        $this->notification = $notification;
        $this->queue        = 'im';
    }

    /**
     * Execute the job.
     *
     * @return void
     * @throws \Throwable
     */
    public function handle(): void
    {
        $this->notification->update(['status' => NotificationStatusEnum::PROCESSING]);

        $batch = Bus::batch([]);

        NotificationUser::query()->where('notification_id', $this->notification->getKey())
            ->chunkById(400, fn(Collection $collection) => $batch->add(new SystemNotificationSendItemJob($this->notification, $collection)));

        $batch->name('SystemNotificationSend-' . $this->notification->getKey())
            ->withOption('notification_id', $this->notification->getKey())
            ->finally(function (Batch $batch) {
                Notification::query()->whereKey($batch->options['notification_id'])->update([
                    'status' => NotificationUser::query()
                        ->where('notification_id', $batch->options['notification_id'])
                        ->where('status', NotificationStatusEnum::SUCCESS)
                        ->exists() ? NotificationStatusEnum::SUCCESS : NotificationStatusEnum::FAIL
                ]);
            })
            ->allowFailures()->dispatch();
    }
}