Artisan 小王子 作品分享

chowjiawei發表於2021-11-23

作為Artisan 小王子

我要分享下

專案裡面的Artisan命令 拿出來2個命令 給大家瞅瞅 。

主命令內部執行其他我做的小命令

小命令程式碼不給你們看了,涉及業務,給你們看最外面的主命令框架

命令的進度條根據愛好給你們分享2種方式

錄屏gif軟體剛剛找的 特別好用 也給你們了

Laravel

Artisan 小王子 作品

<?php

namespace App\Console\Commands;

use App\Models\Option;
use Cache;
use DB;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Artisan;

class MainCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'main {--key= :  步驟}';

    /**
     * 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 mixed
     */
    public function handle()
    {
        //TODO 關於正式環境的所有操作都必須保證,只允許執行一次,產生資料後禁止執行
//        $this->productionCheckHint();
        $exit = 'no';
        do {
            $key = $this->option('key');
            if ($key) {
                //其他不開放快速執行
                if ($key == 3) {
                    $option = '網站全站加速';
                }
                if ($key == 2) {
                    $option = '一鍵部署';
                }
            } else {
                $option = $this->choice('請選擇功能', [
                    '新建使用者/修改使用者',
                    '業務通知',
                    '一鍵部署',
                    '網站全站加速',
                    '基金股票關係表生成',
                ]);
            }
            $this->line('正在為您連結 ' . $option);
            switch ($option) {
                case '新建使用者/修改使用者':
                    $name = $this->ask('請輸入新建/修改使用者的名字');
                    $email = $this->ask('請輸入新建/修改使用者的郵箱');
                    $password = $this->ask('請輸入新建/修改使用者的密碼');
                    Artisan::call("user:generate $name $email $password");
                    $message = '為您強制新建/更新使用者成功!';
                    break;
                case '業務通知':
                    $text = $this->ask('請輸入要通知的文字');
                    $robotKey = $this->ask('請輸入需要通知的機器人Key,不輸入則使用系統env預設企業微信機器人');
                    if ($robotKey) {
                        Artisan::call("business:notify " . '--text='.$text . "--key=$robotKey ");
                    }
                    Artisan::call("business:notify " . '--text='.$text);
                    $message = '通知傳送完成';
                    break;
                case '一鍵部署':
                    if (App::environment('production')) {
                        $this->output->error('檢測到您處於生產模式,無法為您進行操作,請確認您的環境APP_ENV不為production後在執行');
                        return ;
                    }
                    try {
                        if (Option::get('main_command_is_used')) {
                            $this->output->error('本命令只允許使用一次,確保不被惡意攻擊,命令內部終止');
                            return ;
                        }
                    } catch (\Exception $exception) {
                    }
                    $this->output->success('部署前的檢查已經完成');
                    if($this->confirm('開始部署?')){

                        Artisan::call("key:generate");
                        $this->output->title('');
                        $this->output->success('網站金鑰填充成功');

                        Artisan::call("migrate:refresh");
                        $this->output->title('');
                        $this->output->success('資料庫重灌並遷移完成');

                        Artisan::call("passport:install");
                        $this->output->title('');
                        $this->output->success('passport金鑰已生成');

                        Artisan::call("db:seed");
                        $this->output->title('');
                        $this->output->success('資料填充完畢');

                        Artisan::call("storage:link");
                        $this->output->title('');
                        $this->output->success('storage軟連線生成');

                        Artisan::call('optimize:clear');
                        $this->output->title('');
                        $this->output->success('整站快取清理完成');

                        $this->output->title('');
                        $this->output->title('正在為您生成股票關係表,此項可能較久,請耐心等待');
                        Artisan::call('fund-shares:generate');

                        $this->output->success('股票關係表已經生成最新資料');
                        Option::set('main_command_is_used', true);
                        $this->output->success('命令正在完成,完成後,該命令將永久不可用');

                        $this->output->title('首次部署完畢後,請執行一次網站全站加速');

                        if ($this->option('key')==2) {
                            $this->output->info('完成,為您退出命令!');
                            return ;
                        }
                        $this->output->info('完成,您可以退出命令!');
                    }

                    break;
                case '網站全站加速':
                    $this->output->progressStart(100);
                    $client = new Client();
                    $this->output->title('加速馬上開始,加速過程中可能會給網站造成臨時的緩慢');
                    $this->output->title('正在做加速前的檢查........');
                    $url = config('app.url');
                    if ($url) {
                        try {
                            $client->get($url);
                            $this->output->success('網站URL配置正確及連線正常');
                        } catch (\Exception $e) {
                            $this->output->error('網站URL不可連線!加速無法進行,請確保您的網站連線是否正常');
                            return ;
                        }
                    } else {
                        $this->output->error('網站URL缺失,加速無法進行,請確保您的env檔案專案url正常!');
                        return ;
                    }

                    $this->output->title('正在檢測網站redis服務連線性');
                    if (config('cache.default') !== 'redis' || config('queue.default') !== 'redis') {
                        $this->output->error('檢測到網站快取或佇列非redis模式!加速無法進行,請修改env配置檔案!');
                        return ;
                    } else {
                        if (Cache::put('test', 'test', 3)) {
                            $this->output->success('網站已啟用redis伺服器,redis伺服器連線正常');
                        } else {
                            $this->output->error('redis伺服器連線失敗,請檢查redis伺服器狀態');
                        }
                    }
                    $this->output->title('加速選項-1-正在加速 -該項加速失敗率較高,時間較久請耐心等待');
                    $this->output->progressAdvance(25);
                    $i = 0;
                    $tryMaxNum = config('url-speed.try_times');
                    while ($i < $tryMaxNum) {
                        try {
                            Artisan::call('url-speed:generate 1 --conditional');
                            break;
                        } catch (\Exception $e) {
                            $i++;
                            $this->output->error('很遺憾由於您的伺服器配置問題,本次加速未能完成,正在為您重試第'.$i.'次!');
                        }
                    }

                    if ($i === $tryMaxNum) {
                        $this->output->error('加速選項- 1 -加速失敗-跳過【您可以稍後再次執行本命令,加速過的部分將會為您跳過!並且建議您將速度配置調低以確保穩定性】');
                    }
                    $this->output->title('');
                    $this->output->success('加速選項-1-加速完畢');
                    $this->output->title('加速選項-2-正在加速');
                    $this->output->progressAdvance(25);
                    Artisan::call("url-speed:generate 1 --bullfund");
                    $this->output->title('');
                    $this->output->success('加速選項-2-加速完畢');
                    $this->output->title('加速選項-3-正在加速');
                    $this->output->progressAdvance(25);
                    Artisan::call("url-speed:generate 1 --real");
                    $this->output->title('');
                    $this->output->success('加速選項-3-加速完畢');
                    $this->output->title('加速選項-4-正在加速');
                    $this->output->progressAdvance(25);
                    Artisan::call("url-speed:generate 1 --other");
                    $this->output->title('');
                    $this->output->success('加速選項-4-加速完畢');
                    $this->output->progressFinish();
                    if ($this->option('key')==3) {
                        $this->output->info('完成,為您退出命令!');
                        return ;
                    }
                    $this->output->info('完成,您可以退出命令!');
                    break;

                default:
                    $message = '請選擇';
            }
            $this->output->title($message ?? '');
            $exit = $this->confirm('需要退出本系統嗎?');
        } while ($exit != 'yes');
    }
}

如果加速的條件多了,最好可以最佳化一下下,最佳化程式碼如下:

<?php

namespace App\Console\Commands;

use App\Models\Option;
use Cache;
use DB;
use GuzzleHttp\Client;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Artisan;

class MainCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'main {--key= :  步驟}';

    /**
     * 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 mixed
     */
    public function handle()
    {
        //TODO 關於正式環境的所有操作都必須保證,只允許執行一次,產生資料後禁止執行
//        $this->productionCheckHint();
        $exit = 'no';
        do {
            $key = $this->option('key');
            if ($key) {
                //其他不開放快速執行
                if ($key == 3) {
                    $option = '網站全站加速';
                }
                if ($key == 2) {
                    $option = '一鍵部署';
                }
            } else {
                $option = $this->choice('請選擇功能', [
                    '新建使用者/修改使用者',
                    '業務通知',
                    '一鍵部署',
                    '網站全站加速',
                    '基金股票關係表生成',
                ]);
            }
            $this->line('正在為您連結 ' . $option);
            switch ($option) {

                case '網站全站加速':
                    $this->output->progressStart(100);

                    $this->output->title('加速馬上開始,加速過程中可能會給網站造成臨時緩慢,請耐心等待');
                    $this->output->title('正在做加速前的檢查........');
                    if ($this->healthCheckForWebSite()!==0) {
                        return ;
                    }

                    $urlSpeedTypes=['conditional','bullfund','real','other'];
                    foreach ($urlSpeedTypes as $key => $urlSpeedType) {
                        $this->output->title('加速選項-'.$key.'-正在加速');
                        $this->output->progressAdvance(25);
                        $this->tryTimesSpeed($urlSpeedType, $key);
                    }

                    $this->output->progressFinish();

                    if ($this->option('key')==3) {
                        $this->output->info('完成,為您退出命令!');
                        return ;
                    }
                    $this->output->info('完成,您可以退出命令!');
                    break;

                default:
                    $message = '請選擇';
            }
            $this->output->title($message ?? '');
            $exit = $this->confirm('需要退出本系統嗎?');
        } while ($exit != 'yes');
    }

    public function tryTimesSpeed($type, $times)
    {
        $i = 0;
        $tryMaxNum = config('url-speed.try_times');
        while ($i < $tryMaxNum) {
            try {
                Artisan::call('url-speed:generate 1 --'.$type);
                break;
            } catch (\Exception $e) {
                $i++;
                $this->output->error('很遺憾由於您的伺服器配置問題,本次加速未能完成,正在為您重試第'.$i.'次!');
            }
        }

        if ($i === $tryMaxNum) {
            $this->output->error('加速選項- '.$times.' -加速失敗-跳過【您可以稍後再次執行本命令,加速過的部分將會為您跳過!並且建議您將速度配置調低以確保穩定性】');
        }

        $this->output->title('');
        $this->output->success('加速選項-'.$times.'-加速完畢');
    }


    public function healthCheckForWebSite(): int
    {
        $client = new Client();
        $url = config('app.url');
        $result=0;




        $this->output->title('正在檢測網站URL相關內容');
        if ($url) {
            try {
                $client->get($url);
                $this->output->success('網站URL配置正確及連線正常');
            } catch (\Exception $e) {
                $this->output->error('網站URL不可連線!加速無法進行,請確保您的網站連線是否正常');
                $result+=1;
            }
        } else {
            $this->output->error('網站URL缺失,加速無法進行,請確保您的env檔案專案url正常!');
            $result+=1;
        }



        $this->output->title('正在檢測網站redis服務連線性');
        if (config('cache.default') !== 'redis' || config('queue.default') !== 'redis') {
            $this->output->error('檢測到網站快取或佇列非redis模式!加速無法進行,請修改env配置檔案!');
            $result+=1;
        } else {
            try {
                if (Cache::put('test', 'test', 1)) {
                    $this->output->success('網站已啟用redis伺服器,redis伺服器連線正常');
                }
            } catch (\Exception $e) {
                $this->output->error('redis伺服器連線失敗,請檢查redis伺服器狀態');
                $result+=1;
            }
        }



        return $result;
    }
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章