動態

詳情 返回 返回

Dcat Admin 為模型生成器追加屬性註解 - 動態 詳情

Dcat Admin 自帶了 Model 模型生成器,但生成的類中並沒有表字段對應的 @property 屬性註解,這裏對源碼做了一些修改和完善,增加了對應字段的註解。

NOTICE: 僅限使用數據庫中已存在的表生成模型類的場景,如果是通過面板創建新表則不能(兼容起來太麻煩了)

需要修改或配置如下3文件

1. 模型類模版

src/Scaffold/stubs/model.stub

<?php

namespace DummyNamespace;

DummyImportDateTimeFormatterTrait
DummyImportSoftDeletesTrait
use Illuminate\Database\Eloquent\Model;

/**
 * 創建時間 DummyCreatedAt
 * @package DummyNamespace
 *
DummyComments
 */
class DummyClass extends Model
{
    DummyUseDateTimeFormatterTrait
    DummyUseSoftDeletesTrait

    DummyModelTable
    DummyModelKey
    DummyTimestamp

    DummyCasts
}

2. 模型類生成器

\Dcat\Admin\Scaffold\ModelCreator:新增 replaceComment 方法,並在 create 方法中註冊。

    /**
     * The connection of database.
     * @var string
     */
    protected string $connection;

    /**
     * ModelCreator constructor.
     *
     * @param  string  $tableName
     * @param  string  $name
     * @param  null  $files
     * @param  string  $connection
     */
    public function __construct($tableName, $name, $files = null, string $connection = '')
    {
        $this->tableName = $tableName;

        $this->name = $name;

        $this->files = $files ?: app('files');
        
        $this->connection = $connection ?: config('database.default');
    }

    /**
     * Create a new migration file.
     *
     * @param  string  $keyName
     * @param  bool|true  $timestamps
     * @param  bool|false  $softDeletes
     * @return string
     *
     * @throws \Exception
     */
    public function create($keyName = 'id', $timestamps = true, $softDeletes = false)
    {
        ...
        $stub = $this->replaceClass($stub, $this->name)
            ->replaceNamespace($stub, $this->name)
            ->replaceSoftDeletes($stub, $softDeletes)
            ->replaceDatetimeFormatter($stub)
            ->replaceTable($stub, $this->name)
            ->replaceTimestamp($stub, $timestamps)
            ->replacePrimaryKey($stub, $keyName)
            ->replaceComments($stub, $timestamps, $softDeletes)
            ->replaceSpace($stub);
        ....
    }


    /**
     * replace comment.
     * @param $stub
     * @param $userTimestamps
     * @param $userSoftDeletes
     *
     * @return $this
     */
    public function replaceComments(&$stub, $userTimestamps = true, $userSoftDeletes = false)
    {
        $table_name           = config('database.connections.'.$this->connection.'.prefix').$this->tableName;
        $db_name              = config('database.connections.'.$this->connection.'.database');
        $column_type_mappings = config('database.column_type_mappings');
        
        $sql = "SELECT `column_name`,`column_comment`,`data_type` FROM `information_schema`.`columns` WHERE `table_name`='".$table_name."' AND `table_schema`='".$db_name."'";
        
        $columns = DB::connection($this->connection)->select($sql);
        
        $casts = [];
        if ($columns) {
            foreach ($columns as $key => $column) {
                $type = $column_type_mappings[$column->data_type] ?? 'unknown';
                $comments[]  = " * @property $type $column->column_name $column->column_comment";
                if ('datetime' == $type || '\Carbon\Carbon' == $type) {
                    $casts[$column->column_name] = 'datetime';
                }
                if ('array' == $type) {
                    $casts[$column->column_name] = 'json';
                }
            }
        }
        
        $comments = implode(PHP_EOL, $comments);
        $stub     = str_replace('DummyComments', $comments, $stub);
        $stub     = str_replace('DummyCreatedAt', Carbon::now()->toDateTimeString(), $stub);
        $stub     = str_replace('DummyCasts', 'protected $casts = '.var_export($casts, true) . ';', $stub);
        
        return $this;
    }

3. 模型屬性類型映射關係

config/database.php

<?php

return [
    // 自定義數據列字段類型映射關係
    'column_type_mappings' => [
        'bit'       => 'int',
        'tinyint'   => 'int',
        'smallint'  => 'int',
        'mediumint' => 'int',
        'int'       => 'int',
        'integer'   => 'int',
        'bigint'    => 'int',
        
        'decimal' => 'float',
        'numeric' => 'float',
        'float'   => 'float',
        'double'  => 'float',
        
        'date'      => 'string',
        'time'      => 'string',
        'datetime'  => '\Carbon\Carbon',
        'timestamp' => '\Carbon\Carbon',
        'year'      => 'string',
        
        'char'       => 'string',
        'varchar'    => 'string',
        'tinytext'   => 'string',
        'text'       => 'string',
        'mediumtext' => 'string',
        'longtext'   => 'string',
        
        'binary'     => 'string',
        'varbinary'  => 'string',
        'tinyblob'   => 'string',
        'blob'       => 'string',
        'mediumblob' => 'string',
        'longblob'   => 'string',
        
        'enum' => 'array',
        'set'  => 'array',
        'json' => 'array',
    ],
]

附加一個命令行工具類

<?php

namespace App\Console\Commands;

use Dcat\Admin\Scaffold\ModelCreator;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema;

/**
 * 生成模型 自動添加註解
 * Class MakeModelCmd
 * php artisan app:model-creator users User [-c mysql -t -s -r]
 * @package App\Console\Commands
 */
class ModelCreatorCmd extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'app:model-creator
    {table : Name of the table in database: users}
    {model : Name of the model: User or full namespace like App\\Models\\User}
    {--c|connection= : connection name}
    {--t|timestamps : turn on timestamps}
    {--s|softDelete : turn on softDelete}
    {--r|rewrite : turn on rewrite}';
    
    /**
     * 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 int
     * @throws \Exception
     */
    public function handle(): int
    {
        $table      = $this->argument('table');
        $model      = $this->argument('model');
        $connection = $this->option('connection') ?: config('database.default');
        
        // 如果沒有指定命名空間,則默認加上App\Models
        if (!str_contains($model, '\\')) {
            $model = 'App\\Models\\'.ucfirst($model);
        }
        
        $mc         = (new ModelCreator($table, $model, null, $connection));
        $model_path = $mc->getPath($model);
        
        // 如果文件存在且需要重寫,則刪除原文件
        if (File::exists($model_path) && $this->option('rewrite')) {
            File::delete($model_path);
        }
        $model_path = $mc->create('id',
            $this->option('timestamps'),
            $this->option('softDelete')
        );
        $this->info("Model created successfully: {$model_path}");
        return self::SUCCESS;
    }
}
user avatar tpwonline 頭像 sy_records 頭像 yanwushu 頭像 huifeideniao 頭像 manongsir 頭像
點贊 5 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.