当前位置: 首页 > 工具软件 > Laravel-Phone > 使用案例 >

laravel-admin自定义命令生成模型和控制器并添加路由

韦修文
2023-12-01
class GosAutoAdmin extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'gos:admin {table} {model} {modelTitle}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = '自动生成后台代码';

    /**
     * @var array
     */
    protected $formats = [
        'form_field'  => "\$form->%s('%s', __('%s'))",
        'show_field'  => "\$show->field('%s', __('%s'))",
        'grid_column' => "\$grid->column('%s', __('%s'))",
    ];

    /**
     * @var array
     */
    protected $fieldTypeMapping = [
        'ip'       => 'ip',
        'email'    => 'email|mail',
        'password' => 'password|pwd',
        'url'      => 'url|link|src|href',
        'mobile'   => 'mobile|phone',
        'color'    => 'color|rgb',
        'image'    => 'image|img|avatar|pic|picture|cover',
        'file'     => 'file|attachment',
    ];

     /**
      * 控制器名称
     * @var string
     */
    protected $controllerName;

    /**
     * 模型名称
     * @var string
     */
    protected $modelName;

     /**
     * 数据表名称
     * @var string
     */
    protected $tableName;

    /**
     * 页面显示的标题
     * @var string
     */
    protected $modelTitle;

     /**
     * 所有表字段
     * @var string
     */
    protected $columns;

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

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $this->modelName = $this->getModelName();
        $this->modelTitle = $this->getModelTitle();
        $this->tableName = $this->getTableName();
        if (empty($this->modelName) || empty($this->tableName) || empty($this->modelTitle)) {
            $this->error('命令不正确!');
            return false;
        }

        $this->columns = $this->getColumns();
        $modelExists = $this->modelExists();
        $canMakeController = false;
        if (!$modelExists) {
            $createModel = $this->replaceModel();
            if ($createModel !== false) {
                $canMakeController = true;
            } else {
                $this->error('创建模型失败!');
                return false;
            }
        } else {
            $canMakeController = true;
        }

        if ($canMakeController) {
            $this->controllerName = $this->getControllerName();
            $createController = $this->replaceController();
            if ($createController === false) {
                $this->error('创建控制器失败!');
                return false;
            } 
            $this->addRoute();
        } 

        $this->info('创建'.$this->modelTitle.'成功!');
        $this->info($this->modelName);
        $this->info($this->controllerName);
        return true;
    }

    /**
     * 获取模型名称,包括命名空间
     */
    protected function getModelName()
    {
        $model = $this->argument('model');
        return 'App\\Models\\' . $model;
    }

    /**
     * 获取表名称
     */
    protected function getTableName()
    {
        return$this->argument('table');
    }

    /**
     * 获取控制器名称,包括命名空间
     */
    protected function getControllerName()
    {
        $model = $this->argument('model');
        $namespace = $this->getAdminNamespace();
        return $namespace . '\\' . $model . "Controller";
    }

    /**
     * 获取页面标题
     */
    protected function getModelTitle()
    {
        return $this->argument('modelTitle');
    }

    /**
     * 获取控制器模板
     */
    protected function getControllerStub()
    {
        
        if ($this->modelName) {
            return __DIR__.'/stubs/controller.stub';
        }
    }

     /**
     * 获取控制器模板
     */
    protected function getModelStub()
    {
        if ($this->modelName) {
            return __DIR__.'/stubs/model.stub';
        }
    }

    /**
     * 获取路由文件
     */
    protected function getRouteFile() 
    {
        return app_path().'/Admin/routes.php';
    }

    /**
     * 获取命名空间
     */
    protected function getAdminNamespace()
    {
        return config('admin.route.namespace');
    }

    protected function indentCodes($code)
    {
        $indent = str_repeat(' ', 8);

        return rtrim($indent.preg_replace("/\r\n/", "\r\n{$indent}", $code));
    }

    /**
     * 获取表字段
     */
    protected function getColumns()
    {
        $schema = DB::connection()->getDoctrineSchemaManager($this->tableName);
        return $schema->listTableColumns($this->tableName);
    }

    /**
     * 判断模型是否存在
     */
    protected function modelExists()
    {
        return class_exists($this->modelName) && \is_subclass_of($this->modelName, Model::class);
    }
   

    /**
     * 控制器模板变量替换
     */
    protected function replaceController()
    {
        $stub = $this->getControllerStub();
        $template = file_get_contents($stub);
        $namespace = $this->getAdminNamespace();
        $className = class_basename($this->controllerName);
        $file =  app_path() . '/Admin/Controllers/' . $className . '.php';
        
      

        $content =  str_replace(
            [
                'DummyNamespace',
                'DummyModelNamespace',
                'DummyClass',
                'DummyTitle',
                'DummyModel',
                'DummyGrid',
                'DummyShow',
                'DummyForm',
            ],
            [
                $namespace,
                $this->modelName,
                $className,
                $this->getModelTitle(),
                class_basename($this->modelName),
                $this->indentCodes($this->generateGrid()),
                $this->indentCodes($this->generateShow()),
                $this->indentCodes($this->generateForm()),
            ],
            $template
        );
        return file_put_contents($file, $content);
    }

    /**
     * 模型模板变量替换
     */
    protected function replaceModel()
    {
        $stub = $this->getModelStub();
        $template = file_get_contents($stub);
        $className = class_basename($this->modelName);
        $file =  app_path() . '/Models/' . $className . '.php';
        $fileds = '';
        if (count($this->columns) > 0) {
            foreach($this->columns as $column) {
                $columnName = $column->getName();
                $fileds .= sprintf("'%s',", $columnName);
            }
            $fileds = rtrim($fileds, ',');
        }

        $content = str_replace(
            [
                'DummyModelClass',
                'TableName',
                'DummyFills'
            ],
            [
                $className,
                '"'.$this->tableName . '"',
                $fileds
            ],
            $template
        );
        return file_put_contents($file, $content);
    }

    /**
     * 添加路由
     */
    protected function addRoute()
    {
        $file = $this->getRouteFile();
        $template = file_get_contents($file);
        $className = class_basename($this->controllerName);
        //$router->resource('users', UserController::class);
        $resource =  "\t \$router->resource('%s', %s)";
        $newEnd = sprintf($resource, $this->tableName, $className.'::class') . ";\r\n});";
        $content = str_replace(
           '});',
           $newEnd,
            $template
        );
        return file_put_contents($file, $content);
    }

    /**
     * @return string
     */
    public function generateForm()
    {
    
        $output = '';

        foreach ($this->columns as $column) {
            $name = $column->getName();
            if (in_array($name, ['id', 'created_at', 'updated_at', 'deleted_at'])) {
                continue;
            }
            $type = $column->getType()->getName();
            $default = $column->getDefault();

            $defaultValue = '';

            // set column fieldType and defaultValue
            switch ($type) {
                case 'boolean':
                case 'bool':
                    $fieldType = 'switch';
                    break;
                case 'json':
                case 'array':
                case 'object':
                    $fieldType = 'text';
                    break;
                case 'string':
                    $fieldType = 'text';
                    foreach ($this->fieldTypeMapping as $type => $regex) {
                        if (preg_match("/^($regex)$/i", $name) !== 0) {
                            $fieldType = $type;
                            break;
                        }
                    }
                    $defaultValue = "'{$default}'";
                    break;
                case 'integer':
                case 'bigint':
                case 'smallint':
                case 'timestamp':
                    $fieldType = 'number';
                    break;
                case 'decimal':
                case 'float':
                case 'real':
                    $fieldType = 'decimal';
                    break;
                case 'datetime':
                    $fieldType = 'datetime';
                    $defaultValue = "date('Y-m-d H:i:s')";
                    break;
                case 'date':
                    $fieldType = 'date';
                    $defaultValue = "date('Y-m-d')";
                    break;
                case 'time':
                    $fieldType = 'time';
                    $defaultValue = "date('H:i:s')";
                    break;
                case 'text':
                case 'blob':
                    $fieldType = 'textarea';
                    break;
                default:
                    $fieldType = 'text';
                    $defaultValue = "'{$default}'";
            }

            $defaultValue = $defaultValue ?: $default;

            $label = $this->formatLabel($name);

            $output .= sprintf($this->formats['form_field'], $fieldType, $name, $label);

            if (trim($defaultValue, "'\"")) {
                $output .= "->default({$defaultValue})";
            }

            $output .= ";\r\n";
        }

        return $output;
    }

    public function generateShow()
    {
        $output = '';

        foreach ($this->columns as $column) {
            $name = $column->getName();

            // set column label
            $label = $this->formatLabel($name);

            $output .= sprintf($this->formats['show_field'], $name, $label);

            $output .= ";\r\n";
        }

        return $output;
    }

    public function generateGrid()
    {
        $output = '';

        foreach ($this->columns as $column) {
            $name = $column->getName();
            $label = $this->formatLabel($name);

            $output .= sprintf($this->formats['grid_column'], $name, $label);
            $output .= ";\r\n";
        }

        return $output;
    }

    /**
     * Format label.
     *
     * @param string $value
     *
     * @return string
     */
    protected function formatLabel($value)
    {
        return ucfirst(str_replace(['-', '_'], ' ', $value));
    }
}

 

 类似资料: