BrokerPushLevelRecordCreateJob.php 3.79 KB
<?php

namespace App\Jobs;

use App\Models\BrokerPushConfig;
use App\Models\BrokerPushLevelRecord;
use App\Models\BrokerPushLevelRecordItem;
use App\Models\BrokerUserConfig;
use App\Models\BrokerUserConfigItem;
use Carbon\Carbon;
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\SerializesModels;
use Illuminate\Support\Facades\DB;

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

    public BrokerUserConfig $config;

    public int $operateId;

    public Carbon $publishAt;

    public bool $isAlert;

    public Collection $messageTemplate;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(BrokerUserConfig $config, int $operateId, Carbon $publishAt, bool $isAlert)
    {
        $this->config          = $config;
        $this->operateId       = $operateId;
        $this->publishAt       = $publishAt;
        $this->isAlert         = $isAlert;
        $this->messageTemplate = BrokerPushConfig::query()->where('level_title', '!=', '')->get(['id', 'identifier', 'level_title', 'level_intro']);
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle(): void
    {
        DB::transaction(function () {
            $record = BrokerPushLevelRecord::query()->create([
                'user_id'    => $this->operateId,
                'config_id'  => $this->config->getKey(),
                'title'      => $this->config->getAttribute('title'),
                'begin_at'   => $this->config->getAttribute('begin_at'),
                'end_at'     => $this->config->getAttribute('end_at'),
                'publish_at' => $this->publishAt->toDateTimeString(),
                'is_alert'   => (int)$this->isAlert,
            ]);

            BrokerUserConfigItem::with('user:id,nick_name')
                ->where('config_id', $this->config->getKey())
                ->where('status', 1)
                ->chunkById(500, function (Collection $collection) use ($record) {
                    $data = [];
                    $now  = now()->toDateTimeString();
                    $collection->each(function (BrokerUserConfigItem $item) use (&$data, $record, $now) {
                        if ($template = $this->messageTemplate->firstWhere('identifier', $item->getAttribute('identifier'))) {
                            $data[] = [
                                'record_id'  => $record->getKey(),
                                'user_id'    => $item->getAttribute('user_id'),
                                'title'      => $template->getAttribute('level_title'),
                                'content'    => $this->formatContent($item, $template),
                                'created_at' => $now, 'updated_at' => $now
                            ];
                        }
                    });

                    if (count($data) !== 0) {
                        BrokerPushLevelRecordItem::query()->insert($data);
                    }
                });
        });
    }

    /**
     * @param \App\Models\BrokerUserConfigItem $item
     * @param \App\Models\BrokerPushConfig     $template
     * @return string
     */
    public function formatContent(BrokerUserConfigItem $item, BrokerPushConfig $template): string
    {
        return str_replace(['{border}', '{type}', '{start}', '{end}'], [
            $item->getAttribute('user')?->getAttribute('nick_name') ?? '',
            $item->getAttribute('identifier') ?? '',
            $this->config->getAttribute('begin_at'),
            $this->config->getAttribute('end_at'),
        ], $template->getAttribute('level_intro'));
    }
}