BrokerPushLevelRecordRollBackJob.php 2.16 KB
<?php

namespace App\Jobs;

use App\Enums\BrokerPushLevelRecordStatusEnum;
use App\Enums\BrokerPushMatchRecordStatusEnum;
use App\Models\BrokerPushLevelRecord;
use App\Models\BrokerPushLevelRecordItem;
use Illuminate\Bus\Batch;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Bus;

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

    public BrokerPushLevelRecord $record;

    public function middleware(): array
    {
        return [new WithoutOverlapping($this->record->getKey())];
    }

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(BrokerPushLevelRecord $record)
    {
        $this->record = $record;
        $this->queue  = 'im_rollback';
    }

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

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

        BrokerPushLevelRecordItem::query()->where('record_id', $this->record->getKey())
            ->where('status', BrokerPushLevelRecordStatusEnum::SUCCESS)
            ->eachById(fn(BrokerPushLevelRecordItem $item) => $batch->add(new BrokerPushLevelRecordItemRollBackJob($item)));

        $batch->name('BrokerPushLevelRecordRollBack-' . $this->record->getKey())
            ->withOption('record_id', $this->record->getKey())
            ->finally(function (Batch $batch) {
                $isSuccess = BrokerPushLevelRecordItem::query()->where('record_id', $batch->options['record_id'])->where('status', 3)->exists();
                BrokerPushLevelRecord::query()->whereKey($batch->options['record_id'])
                    ->update(['status' => $isSuccess ? BrokerPushLevelRecordStatusEnum::ROLLBACK : BrokerPushMatchRecordStatusEnum::SUCCESS]);
            })
            ->allowFailures()->dispatch();
    }
}