EventExpend.php 10.5 KB
<?php
/**
 * Created by PhpStorm.
 * User: zhl
 * Date: 2022/11/05
 * Time: 14:11
 */
namespace App\Console\Commands;

use App\Models\BtEvents;
use App\Repositories\BtRepository;
use App\Repositories\ToolRepository;
use Illuminate\Console\Command;

/**
 * Class EventExpend
 * @package App\Console\Commands
 */
class EventExpend extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'event:expend';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '消费提交事件';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return bool
     */
    public function handle()
    {
        while (true) {
            $start_at = date('Y-m-d H:i:s');
            $events = BtEvents::where('status', 0)->where('times', '<', BtEvents::MAX_TRIES_TIMES)->where('start_at', '<', $start_at)->orderBy('id', 'asc')->limit(10)->get();
            // 没有需要处理的数据
            if ($events->isEmpty()) {
                echo $start_at . ', empty event.' . PHP_EOL;
                sleep(30);
            } else {
                $this->expend($events);
            }
        }
        return true;
    }

    /**
     * @param $data
     * @return bool
     */
    public function expend($data)
    {
        foreach ($data as $val) {
            $param = json_decode($val->param, true);
            switch ($val->type) {
                case BtEvents::TYPE_CREATE_SITE:
                    $result = $this->createSiteEvent($val->id, $param);
                    break;
                case BtEvents::TYPE_DELETE_SITE:
                    $result = $this->deleteSiteEvent($val->id, $param);
                    break;
                case BtEvents::TYPE_CREATE_SSL:
                    $result = $this->createSiteSsl($val->id, $param);
                    break;
                case BtEvents::TYPE_RENEWAL_SSL:
                    $result = $this->renewalSiteSsl($val->id, $param);
                    break;
                case BtEvents::TYPE_EVENT_CALLBACK:
                    $result = $this->callbackEvent($val->id, $param);
                    break;
                default:
                    $result = false;
                    break;
            }
        }
        return true;
    }

    /**
     * 创建站点
     * @param $id
     * @param $param
     * @return bool
     */
    public function createSiteEvent($id, $param)
    {
        if (empty($param) || FALSE == is_array($param))
            return false;

        $callback = $param['callback'] ?? '';
        $domain = $param['domain'] ?? '';
        $ssl_open = empty($param['ssl_open']) ? 1 : 0;
        $ssl_auto = empty($param['ssl_auto']) ? 1 : 0;
        $ssl_auto_day = $param['ssl_auto_day'] ?? 10;
        $ssl_auto_day = $ssl_auto_day > 15 ? 15 : max($ssl_auto_day, 5);
        if (empty($domain) || FALSE == filter_var($domain, FILTER_VALIDATE_URL)) {
            if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
                $param['result_status'] = 400;
                $param['result_message'] = 'domain信息错误';
                BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
            }
            return $this->setEvent($id, BtEvents::STATUS_FINISH, 'domain信息错误');
        }

        try {
            $flag = app(BtRepository::class)->createBtSite($domain, $ssl_open, $ssl_auto, $ssl_auto_day);
            $status = $flag ? BtEvents::STATUS_FINISH : BtEvents::STATUS_ERROR;
            $note = $flag ? '' : '创建站点失败';
        } catch (\Exception $e) {
            $status = BtEvents::STATUS_ERROR;
            $note = $e->getMessage();
        }

        if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
            $param['result_status'] = $status == BtEvents::STATUS_FINISH ? 200 : 400;
            $param['result_message'] = $note;
            BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
        }

        return $this->setEvent($id, $status, $note);
    }

    /**
     * 删除站点
     * @param $id
     * @param $param
     * @return bool
     */
    public function deleteSiteEvent($id, $param)
    {
        if (empty($param) || FALSE == is_array($param))
            return false;
        $callback = $param['callback'] ?? '';
        $domain = $param['domain'] ?? '';
        if (empty($domain) || FALSE == filter_var($domain, FILTER_VALIDATE_URL)) {
            if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
                $param['result_status'] = 400;
                $param['result_message'] = 'domain信息错误';
                BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
            }
            return $this->setEvent($id, BtEvents::STATUS_FINISH, 'domain信息错误');
        }

        try {
            $flag = app(BtRepository::class)->deleteBtSite($domain);
            $status = $flag ? BtEvents::STATUS_FINISH : BtEvents::STATUS_ERROR;
            $note = $flag ? '' : '删除站点失败';
        } catch (\Exception $e) {
            $status = BtEvents::STATUS_ERROR;
            $note = $e->getMessage();
        }

        if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
            $param['result_status'] = $status == BtEvents::STATUS_FINISH ? 200 : 400;
            $param['result_message'] = $note;
            BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
        }

        return $this->setEvent($id, $status, $note);
    }

    /**
     * 创建ssl证书
     * @param $id
     * @param $param
     * @return bool
     */
    public function createSiteSsl($id, $param)
    {
        if (empty($param) || FALSE == is_array($param))
            return false;
        $callback = $param['callback'] ?? '';
        $host = $param['host'] ?? '';
        if (empty($host)) {
            if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
                $param['result_status'] = 400;
                $param['result_message'] = 'host信息错误';
                BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
            }
            return $this->setEvent($id, BtEvents::STATUS_FINISH, 'host信息错误');
        }

        try {
            $flag = app(BtRepository::class)->applySsl($host);
            $status = $flag ? BtEvents::STATUS_FINISH : BtEvents::STATUS_ERROR;
            $note = $flag ? '' : '删除站点失败';
        } catch (\Exception $e) {
            $status = BtEvents::STATUS_ERROR;
            $note = $e->getMessage();
        }

        if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
            $param['result_status'] = $status == BtEvents::STATUS_FINISH ? 200 : 400;
            $param['result_message'] = $note;
            BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
        }

        return $this->setEvent($id, $status, $note);
    }

    /**
     * 续签证书
     * @param $id
     * @param $param
     * @return bool
     */
    public function renewalSiteSsl($id, $param)
    {
        if (empty($param) || FALSE == is_array($param))
            return false;
        $callback = $param['callback'] ?? '';
        $host = $param['host'] ?? '';
        if (empty($host)) {
            if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
                $param['result_status'] = 400;
                $param['result_message'] = 'host信息错误';
                BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
            }
            return $this->setEvent($id, BtEvents::STATUS_FINISH, 'host信息错误');
        }

        try {
            $flag = app(BtRepository::class)->renewalSsl($host);
            $status = $flag ? BtEvents::STATUS_FINISH : BtEvents::STATUS_ERROR;
            $note = $flag ? '' : '删除站点失败';
        } catch (\Exception $e) {
            $status = BtEvents::STATUS_ERROR;
            $note = $e->getMessage();
        }

        if (FALSE == empty($callback) && filter_var($callback, FILTER_VALIDATE_URL)) {
            $param['result_status'] = $status == BtEvents::STATUS_FINISH ? 200 : 400;
            $param['result_message'] = $note;
            BtEvents::createBtEvent(BtEvents::TYPE_EVENT_CALLBACK, json_encode($param));
        }

        return $this->setEvent($id, $status, $note);
    }

    /**
     * 回调信息
     * @param $id
     * @param $param
     * @return bool
     */
    public function callbackEvent($id, $param)
    {
        if (empty($param) || FALSE == is_array($param))
            return false;
        $callback = $param['callback'] ?? '';
        if (empty($callback) || FALSE == filter_var($callback, FILTER_VALIDATE_URL))
            return $this->setEvent($id, BtEvents::STATUS_FINISH, 'callback信息错误');
        $status = $param['result_status'];
        $message = $param['result_message'];
        unset($param['result_status']);
        unset($param['result_message']);
        $array = [
            'status' => $status,
            'message' => $message,
            'data' => [],
            'param' => $param
        ];
        list($code, $result) = app(ToolRepository::class)->curlRequest($callback, $array);
        $status = $code == 200 ? BtEvents::STATUS_FINISH : BtEvents::STATUS_ERROR;
        return $this->setEvent($id, $status, $result);
    }


    /**
     * 更新任务状态
     * @param $id
     * @param $status
     * @param string $note
     * @return bool
     */
    public function setEvent($id, $status, $note = '')
    {
        $event = BtEvents::where(['id' => $id])->first();
        if (empty($event))
            return false;

        $times = $event->times + 1;

        if ($status == BtEvents::STATUS_ERROR && $times < BtEvents::MAX_TRIES_TIMES) {
            $status = BtEvents::STATUS_INIT;
            // 第一次执行失败以后, 5分钟后再执行一次; 第二次执行失败以后, 10分钟后再执行一次   0->5->15
            if ($times == 1)
                $event->start_at = date('Y-m-d H:i:s', time() + 300);
            if ($times == 2)
                $event->start_at = date('Y-m-d H:i:s', time() + 600);
        }
        $event->status = $status;
        $event->times = $times;
        $event->note = $note;
        $event->save();
        return true;
    }
}