代码生成器

This commit is contained in:
JaguarJack 2020-04-28 22:02:03 +08:00
parent d044ac6d8a
commit 0b546a20be
12 changed files with 376 additions and 72 deletions

View File

@ -1,9 +1,12 @@
<?php <?php
namespace JaguarJack\Generator; namespace catcher\generate;
use catcher\CatchAdmin;
use JaguarJack\Generator\Factory\Controller; use catcher\exceptions\FailedException;
use JaguarJack\Generator\Factory\SQl; use catcher\generate\factory\Controller;
use catcher\generate\factory\Migration;
use catcher\generate\factory\Model;
use catcher\generate\factory\SQL;
class Generator class Generator
{ {
@ -11,15 +14,73 @@ class Generator
{ {
$params = \json_decode($params['data'], true); $params = \json_decode($params['data'], true);
//var_dump((new Controller())->generate($params['controller']));die; [$controller, $model] = $this->parseParams($params);
(new Controller())->done($params['controller']); $message = [];
if ($params['create_controller']) {
if ((new Controller)->done($controller)) {
array_push($message, 'controller created successfully');
}
}
if ($params['create_table']) {
if ((new SQL)->done($model)) {
array_push($message, 'table created successfully');
}
}
if ($params['create_model']) {
if ((new Model)->done($model)) {
array_push($message, 'model created successfully');
}
}
if ($params['create_migration']) {
if ((new Migration)->done([$controller['module'], $model['table']])) {
array_push($message, 'migration created successfully');
}
}
return $message;
} }
public function preview($type, $params) public function preview($type, $params)
{ {
$class = ucfirst($type); $class = ucfirst($type);
(new $class)->done(); (new $class)->done($params);
}
/**
* parse params
*
* @time 2020年04月28日
* @param $params
* @return array[]
*/
protected function parseParams($params)
{
if (!$params['controller']['module'] ?? false) {
throw new FailedException('请设置模块');
}
$controller = [
'module' => $params['controller']['module'],
'model' => $params['controller']['model'] ?? '',
'controller' => $params['controller']['controller'] ?? '',
'restful' => $params['controller']['restful'],
'other_function' => $params['controller']['other_function'],
];
$model = [
'table' => $params['controller']['table'],
'model' => $params['controller']['model'],
'sql' => $params['model']['data'],
'extra' => $params['model']['extra'],
];
return [$controller, $model];
} }
} }

View File

@ -1,8 +1,8 @@
<?php <?php
namespace JaguarJack\Generator\Factory; namespace catcher\generate\factory;
use catcher\exceptions\FailedException; use catcher\exceptions\FailedException;
use JaguarJack\Generator\Template\Controller as Template; use catcher\generate\template\Controller as Template;
use think\helper\Str; use think\helper\Str;
class Controller extends Factory class Controller extends Factory
@ -16,9 +16,29 @@ class Controller extends Factory
* @return bool|string|string[] * @return bool|string|string[]
*/ */
public function done($params) public function done($params)
{
// 写入成功之后
if (file_put_contents($this->getGeneratePath($params['controller']), $this->getContent($params))) {
return (new Route())->controller($params['controller'])
->restful($params['restful'])
->methods($this->parseOtherMethods($params['other_function']))
->done();
}
throw new FailedException($params['controller'] . ' generate failed~');
}
/**
* 获取内容
*
* @time 2020年04月28日
* @param $params
* @return bool|string|string[]
*/
protected function getContent($params)
{ {
if (!$params['controller']) { if (!$params['controller']) {
return false; throw new FailedException('params has lost');
} }
$template = new Template(); $template = new Template();
@ -30,23 +50,30 @@ class Controller extends Factory
// parse model // parse model
[$model, $modelNamespace] = $this->parseFilename($params['model']); [$model, $modelNamespace] = $this->parseFilename($params['model']);
$use = implode(';',[
'use ' . $params['model'] .' as '. $model . 'Model',
]) . ';';
$content = $template->header() . $content = $template->header() .
$template->nameSpace($namespace) . $template->nameSpace($namespace) .
str_replace('{USE}', $model ? 'use ' . $params['model'] .';' : '', $template->uses()) . str_replace('{USE}', $model ? $use : '', $template->uses()) .
$template->createClass($className); $template->createClass($className);
return str_replace('{CONTENT}', ($model ? $template->construct($model.'Model') : '') . rtrim($this->content($params, $template), "\r\n"), $content);
$content = str_replace('{CONTENT}', ($model ? $template->construct($model) : '') . rtrim($this->content($params, $template), "\r\n"), $content);
// 写入成功之后
if (file_put_contents($this->getGeneratePath($params['controller']), $content)) {
(new Route())->controller($params['controller'])
->restful($params['restful'])
->methods($this->parseOtherMethods($params['other_function']))
->done();
}
} }
/**
* parse use
*
* @time 2020年04月28日
* @param $params
* @return string
*/
protected function parseUse($params)
{
}
/** /**
* content * content
* *
@ -77,25 +104,6 @@ class Controller extends Factory
return $content; return $content;
} }
/**
* parse filename
*
* @time 2020年04月27日
* @param $filename
* @return array
*/
public function parseFilename($filename)
{
$namespace = explode('\\', $filename);
$className = ucfirst(array_pop($namespace));
$namespace = implode('\\', $namespace);
return [$className, $namespace];
}
/** /**
* parse $method * parse $method

View File

@ -1,5 +1,5 @@
<?php <?php
namespace JaguarJack\Generator\Factory; namespace catcher\generate\factory;
use catcher\CatchAdmin; use catcher\CatchAdmin;
@ -63,4 +63,22 @@ abstract class Factory
return root_path() . $psr4[$projectRootNamespace.'\\'] . DIRECTORY_SEPARATOR. $module . DIRECTORY_SEPARATOR; return root_path() . $psr4[$projectRootNamespace.'\\'] . DIRECTORY_SEPARATOR. $module . DIRECTORY_SEPARATOR;
} }
/**
* parse filename
*
* @time 2020年04月27日
* @param $filename
* @return array
*/
public function parseFilename($filename)
{
$namespace = explode('\\', $filename);
$className = ucfirst(array_pop($namespace));
$namespace = implode('\\', $namespace);
return [$className, $namespace];
}
} }

View File

@ -0,0 +1,39 @@
<?php
namespace catcher\generate\factory;
use catcher\CatchAdmin;
use catcher\exceptions\FailedException;
use JaguarJack\MigrateGenerator\MigrateGenerator;
class Migration extends Factory
{
public function done($params)
{
[$module, $tableName] = $params;
// TODO: Implement done() method.
$migrationPath = CatchAdmin::directory() . $module . DIRECTORY_SEPARATOR.
'database' . DIRECTORY_SEPARATOR . 'migration' .DIRECTORY_SEPARATOR;
CatchAdmin::makeDirectory($migrationPath);
$migrateGenerator = (new MigrateGenerator('thinkphp'));
$tables = $migrateGenerator->getDatabase()->getAllTables($tableName);
$file = $migrationPath . date('YmdHis') . '_'. $tableName . '.php';
foreach ($tables as $table) {
if ($table->getName() == $tableName) {
file_put_contents($file, $migrateGenerator->getMigrationContent($table));
if (!file_exists($file)) {
throw new FailedException('migration generate failed');
}
break;
}
}
return true;
}
}

View File

@ -1 +1,71 @@
<?php <?php
namespace catcher\generate\factory;
use catcher\exceptions\FailedException;
use catcher\generate\template\Model as Template;
use think\facade\Db;
class Model extends Factory
{
public function done($params)
{
// TODO: Implement done() method.
$template = new Template();
$extra = $params['extra'];
$table = $params['table'];
[$modelName, $namespace] = $this->parseFilename($params['model']);
if (!$modelName) {
throw new FailedException('create Model Failed');
}
$content = $template->useTrait($extra['soft_delete']) .
$template->name($table) .
$template->field($this->parseField($table));
$class = $template->header() .
$template->nameSpace($namespace) .
$template->uses($extra['soft_delete']) .
$template->createModel($modelName, $table);
$file = $this->getGeneratePath($params['model']);
file_put_contents($file, str_replace('{CONTENT}', $content, $class));
if (!file_exists($file)) {
throw new FailedException('create model failed');
}
return true;
}
/**
* parse field
*
* @time 2020年04月28日
* @param $table
* @return string
*/
protected function parseField($table)
{
$columns = Db::query('show full columns from ' .
config('database.connections.mysql.prefix') . $table);
$new = [];
foreach ($columns as $field) {
$new[$field['Field']] = $field['Comment'];
}
$fields = [];
foreach ($new as $field => $comment) {
$fields[] = sprintf("'%s', // %s", $field, $comment);
}
return implode("\r\n\t\t", $fields);
}
}

View File

@ -1 +0,0 @@
<?php

View File

@ -1,7 +1,7 @@
<?php <?php
namespace JaguarJack\Generator\Factory; namespace catcher\generate\factory;
use JaguarJack\Generator\Template\Content; use catcher\generate\template\Content;
class Route extends Factory class Route extends Factory
{ {

View File

@ -1,7 +1,10 @@
<?php <?php
namespace JaguarJack\Generator\Factory; namespace catcher\generate\factory;
use catcher\exceptions\FailedException;
use think\facade\Db;
class SQL class SQL
{ {
protected $index = ''; protected $index = '';
@ -9,19 +12,43 @@ class SQL
public function done($params) public function done($params)
{ {
if ($params['controller']['table'] ?? false) {
return false; //dd($this->createSQL($params));
Db::execute($this->createSQL($params));
// 判断表是否创建成功
if (!$this->hasTableExists($params['table'])) {
throw new FailedException(sprintf('create table [%s] failed',$params['table']));
} }
$table = \config('database.connections.mysql.prefix') . $params['controller']['table']; return true;
}
$extra = $params['model']['extra']; /**
* create table sql
*
* @time 2020年04月28日
* @param $params
* @return string
*/
protected function createSQL($params)
{
if (!$params['table'] ?? false) {
throw new FailedException('table name has lost~');
}
$table = \config('database.connections.mysql.prefix') . $params['table'];
if ($this->hasTableExists($table)) {
throw new FailedException(sprintf('table [%s] has existed', $params['table']));
}
$extra = $params['extra'];
// 主键 // 主键
$createSql = $this->primaryKey($extra['primary_key']); $createSql = $this->primaryKey($extra['primary_key']);
// 字段 // 字段
$ifHaveNotFields = true; $ifHaveNotFields = true;
foreach ($params['model']['data'] as $sql) { foreach ($params['sql'] as $sql) {
if (!$sql['field'] || !$sql['type']) { if (!$sql['field'] || !$sql['type']) {
continue; continue;
} }
@ -30,7 +57,7 @@ class SQL
} }
// 如果没有设置数据库字段 // 如果没有设置数据库字段
if ($ifHaveNotFields) { if ($ifHaveNotFields) {
return false; throw new FailedException('Do you have set mysql fields?');
} }
// 创建时间 // 创建时间
if ($extra['created_at'] ?? false) { if ($extra['created_at'] ?? false) {
@ -44,11 +71,11 @@ class SQL
if ($this->index) { if ($this->index) {
$createSql .= $this->index; $createSql .= $this->index;
} }
$createSql = rtrim($createSql, ',' . PHP_EOL);
// 创建表 SQL // 创建表 SQL
return $this->createTable($table, $createSql, $extra['engine'], 'utf8mb4', $extra['comment']); return $this->createTable($table, $createSql, $extra['engine'], 'utf8mb4', $extra['comment']);
} }
/** /**
* parse sql * parse sql
* *
@ -69,7 +96,7 @@ class SQL
$sql['type'], $sql['type'],
$sql['length'] ? sprintf('(%s)', $sql['length']) : '', $sql['length'] ? sprintf('(%s)', $sql['length']) : '',
$sql['unsigned'] ? 'unsigned' : '', $sql['unsigned'] ? 'unsigned' : '',
$sql['default'] ? 'default ' . $sql['default']: '', $sql['default'] ?? '',
$sql['nullable'] ? 'not null' : '', $sql['nullable'] ? 'not null' : '',
$sql['comment'] ? sprintf('comment \'%s\'', $sql['comment']) : '' $sql['comment'] ? sprintf('comment \'%s\'', $sql['comment']) : ''
]) . ','. PHP_EOL; ]) . ','. PHP_EOL;
@ -139,13 +166,26 @@ class SQL
protected function parseIndex($index, $field) protected function parseIndex($index, $field)
{ {
if ($index == 'unique') { if ($index == 'unique') {
$this->index .= "unique index unique_ . $field($field)"; $this->index .= "unique index unique_$field($field)," . PHP_EOL;
} elseif ($index == 'index') { } elseif ($index == 'index') {
$this->index .= "index($field)"; $this->index .= "index($field),". PHP_EOL;
} elseif ($index == 'fulltext') { } elseif ($index == 'fulltext') {
$this->index .= "fulltext key fulltext_ .$field($field)"; $this->index .= "fulltext key fulltext_$field($field)," . PHP_EOL;
} elseif ($index == 'spatial') { } elseif ($index == 'spatial') {
$this->index .= "spatial index spatial_.$field($field)"; $this->index .= "spatial index spatial_$field($field),". PHP_EOL;
} }
} }
/**
*
* @time 2020年04月28日
* @param $table
* @return bool
*/
protected function hasTableExists($table)
{
$tables = Db::getConnection()->getTables();
return in_array($table, $tables);
}
} }

View File

@ -1,5 +1,5 @@
<?php <?php
namespace JaguarJack\Generator\Template; namespace catcher\generate\template;
trait Content trait Content
{ {

View File

@ -1,5 +1,7 @@
<?php <?php
namespace JaguarJack\Generator\Template; namespace catcher\generate\template;
use catcher\base\CatchController;
class Controller class Controller
{ {
@ -16,6 +18,7 @@ class Controller
return <<<TMP return <<<TMP
use think\Request; use think\Request;
use catcher\CatchResponse; use catcher\CatchResponse;
use catcher\base\CatchController;
{USE} {USE}
@ -48,7 +51,7 @@ TMP;
public function createClass($class) public function createClass($class)
{ {
return <<<TMP return <<<TMP
class {$class} class {$class} extends CatchController
{ {
{CONTENT} {CONTENT}
} }

View File

@ -1,22 +1,88 @@
<?php <?php
namespace JaguarJack\Generator\Template; namespace catcher\generate\template;
trait Model class Model
{ {
use Content; use Content;
public function getList() public function createModel($model, $table)
{ {
return <<<TMP return <<<TMP
public function getList() class {$model} extends Model
{ {
return \$this->catchSearch() {CONTENT}
->order(\$this->getPk(), 'desc')
->paginate();
} }
TMP; TMP;
} }
public function useTrait($hasDeletedAt = true)
{
if (!$hasDeletedAt) {
return <<<TMP
use BaseOptionsTrait;
TMP;
}
}
public function uses($hasDeletedAt = true)
{
if ($hasDeletedAt) {
return <<<TMP
use catcher\base\CatchModel as Model;
TMP;
} else {
return <<<TMP
use think\Model;
use catcher\\traits\db\BaseOptionsTrait;
TMP;
}
}
/**
* name
*
* @time 2020年04月28日
* @param $name
* @return string
*/
public function name($name)
{
return <<<TMP
protected \$name = '{$name}';
TMP;
}
/**
* field
*
* @time 2020年04月28日
* @param $field
* @return string
*/
public function field($field)
{
return <<<TMP
protected \$field = [
{$field}
];
TMP;
}
/** /**
* 一对一关联 * 一对一关联
* *

View File

@ -1,5 +1,5 @@
<?php <?php
namespace JaguarJack\Generator\Template; namespace catcher\generate\template;
trait Request trait Request
{ {