Dcat Admin 自带了模型生成器,但生成的类文件中并没有表列对应的属性注解,这里做补充。
NOTICE
: 仅限使用数据库中已存在的表生成模型类的场景,如果是通过面板创建新表则不能(兼容起来太麻烦了)
需要修改或配置如下3文件
1. 模型类模版
src/Scaffold/stubs/model.stub
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
[
'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',
],
]
附加一个命令行工具类
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;
}
}