first commit

This commit is contained in:
JaguarJack
2022-12-05 23:01:12 +08:00
commit 0024080c28
322 changed files with 27698 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
<?php
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Catch\CatchAdmin;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class Controller extends Creator
{
/**
* @var array
*/
protected array $replace = [
'{namespace}', '{uses}', '{controller}', '{model}', '{request}'
];
/**
* @param string $controller
* @param string $model
* @param string|null $request
*/
public function __construct(
public readonly string $controller,
public readonly string $model,
public readonly ?string $request = null
) {
}
/**
* get file
*
* @return string
*/
public function getFile(): string
{
// TODO: Implement getFile() method.
return CatchAdmin::getModuleControllerPath($this->module).$this->getControllerName().$this->ext;
}
public function getContent(): string|bool
{
// TODO: Implement getContent() method.
return Str::of(File::get($this->getControllerStub()))->replace($this->replace, [
$this->getControllerNamespace(),
$this->getUses(),
$this->getControllerName(),
$this->model,
$this->request ?: 'Request'
])->toString();
}
/**
* get controller name
*
* @return string
*/
protected function getControllerName(): string
{
return Str::of($this->controller)->whenContains('Controller', function ($value) {
return Str::of($value)->ucfirst();
}, function ($value) {
return Str::of($value)->append('Controller')->ucfirst();
})->toString();
}
/**
* get uses
*
* @return string
*/
protected function getUses(): string
{
return Str::of('use ')
->append(CatchAdmin::getModuleModelNamespace($this->module).$this->model)
->append(';')
->newLine()
->append('use ')
->when($this->request, function ($str) {
return $str->append(CatchAdmin::getModuleRequestNamespace($this->module).$this->request);
}, function ($str) {
return $str->append("Illuminate\Http\Request");
})->append(';')->newLine()->toString();
}
/**
* get controller stub
*
* @return string
*/
protected function getControllerStub(): string
{
return dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'controller.stub';
}
/**
* get controller namespace
*
* @return string
*/
protected function getControllerNamespace(): string
{
return Str::of(CatchAdmin::getModuleControllerNamespace($this->module))->rtrim('\\')->append(';')->toString();
}
}

View File

@@ -0,0 +1,112 @@
<?php
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Facades\File;
/**
* creator
*/
abstract class Creator
{
/**
* @var string
*/
protected string $ext = '.php';
/**
* @var string
*/
protected string $module;
/**
* @var string
*/
protected string $file;
/**
* create
*
* @return bool|string
* @throws FileNotFoundException
*/
public function create(): bool|string
{
return $this->put();
}
/**
* the file which content put in
*
* @return string
*/
abstract public function getFile(): string;
/**
* get content
* @return string|bool
*/
abstract public function getContent(): string|bool;
/**
* @return string|bool
* @throws FileNotFoundException
*/
protected function put(): string|bool
{
if (! $this->getContent()) {
return false;
}
$this->file = $this->getFile();
File::put($this->file, $this->getContent());
if (File::exists($this->file)) {
return $this->file;
}
throw new FileNotFoundException("create [$this->file] failed");
}
/**
* set ext
*
* @param string $ext
* @return $this
*/
protected function setExt(string $ext): static
{
$this->ext = $ext;
return $this;
}
/**
* set module
*
* @param string $module
* @return $this
*/
public function setModule(string $module): static
{
$this->module = $module;
return $this;
}
/**
* get file
*
* @return string
*/
public function getGenerateFile(): string
{
return $this->file;
}
}

View File

@@ -0,0 +1,188 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Catch\CatchAdmin;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class FrontForm extends Creator
{
/**
* @var string
*/
protected string $label = '{label}';
/**
* @var string
*/
protected string $prop = '{prop}';
/**
* @var string
*/
protected string $modelValue = '{model-value}';
/**
* @var string
*/
protected string $table = '{table}';
/**
* @var string
*/
protected string $search = '{search}';
/**
* @var string
*/
protected string $api = '{api}';
/**
* @var string
*/
protected string $formItems = '{formItems}';
/**
* @var string
*/
protected string $paginate = '{paginate}';
/**
* @var string
*/
protected string $useList = '{useList}';
/**
* @var array
*/
protected array $structures;
/**
* @param string $controller
*/
public function __construct(protected readonly string $controller)
{
}
/**
* get content
*
* @return string
*/
public function getContent(): string
{
// TODO: Implement getContent() method.
return Str::of(File::get($this->getFormStub()))->replace($this->formItems, $this->getFormContent())->toString();
}
/**
* get file
*
* @return string
*/
public function getFile(): string
{
// TODO: Implement getFile() method.
return CatchAdmin::makeDir(CatchAdmin::getModuleViewsPath($this->module).Str::of($this->controller)->replace('Controller', '')->lcfirst()).DIRECTORY_SEPARATOR.'create.vue';
}
/**
* get form content
*
* @return string
*/
protected function getFormContent(): string
{
$form = Str::of('');
$formComponents = $this->formComponents();
foreach ($this->structures as $structure) {
if ($structure['label'] && $structure['form_component'] && $structure['form']) {
if (isset($formComponents[$structure['form_component']])) {
$form = $form->append(
Str::of($formComponents[$structure['form_component']])
->replace(
[$this->label, $this->prop, $this->modelValue],
[$structure['label'], $structure['field'], sprintf('formData.%s', $structure['field'])]
)
);
}
}
}
return $form->trim(PHP_EOL)->toString();
}
/**
* form components
*
* @return array
*/
protected function formComponents(): array
{
$components = [];
foreach (File::glob(
$this->getFormItemStub()
) as $stub) {
$components[File::name($stub)] = File::get($stub);
}
return $components;
}
/**
* get formItem stub
*
* @return string
*/
protected function getFormItemStub(): string
{
return dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'
.DIRECTORY_SEPARATOR.'vue'.DIRECTORY_SEPARATOR
.'formItems'.DIRECTORY_SEPARATOR.'*.stub';
}
/**
* get form stub
*
* @return string
*/
public function getFormStub(): string
{
return dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'
.DIRECTORY_SEPARATOR.'vue'.DIRECTORY_SEPARATOR.'form.stub';
}
/**
* set structures
*
* @param array $structures
* @return $this
*/
public function setStructures(array $structures): static
{
$this->structures = $structures;
return $this;
}
}

View File

@@ -0,0 +1,252 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Catch\CatchAdmin;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class FrontTable extends Creator
{
/**
* @var string
*/
protected string $label = '{label}';
/**
* @var string
*/
protected string $prop = '{prop}';
/**
* @var string
*/
protected string $modelValue = '{model-value}';
/**
* @var string
*/
protected string $table = '{table}';
/**
* @var string
*/
protected string $search = '{search}';
/**
* @var string
*/
protected string $api = '{api}';
/**
* @var string
*/
protected string $formItems = '{formItems}';
/**
* @var string
*/
protected string $paginate = '{paginate}';
/**
* @var string
*/
protected string $useList = '{useList}';
/**
* @var array
*/
protected array $structures;
/**
* @param string $controller
* @param bool $hasPaginate
* @param string $apiString
*/
public function __construct(
protected readonly string $controller,
protected readonly bool $hasPaginate,
protected readonly string $apiString
) {
}
/**
* get content
*
* @return string
*/
public function getContent(): string
{
// TODO: Implement getContent() method.
return Str::of(File::get($this->getTableStub()))->replace([
$this->table, $this->search, $this->api, $this->paginate, $this->useList
], [
$this->getTableContent(), $this->getSearchContent(),
"'{$this->apiString}'", $this->getPaginateStubContent(), $this->getUseList()
])->toString();
}
/**
* get file
*
* @return string
*/
public function getFile(): string
{
// TODO: Implement getFile() method.
return CatchAdmin::makeDir(CatchAdmin::getModuleViewsPath($this->module).Str::of($this->controller)->replace('Controller', '')->lcfirst()).DIRECTORY_SEPARATOR.'index.vue';
}
/**
* get search content
*
* @return string
*/
protected function getSearchContent(): string
{
$search = Str::of('');
$formComponents = $this->formComponents();
foreach ($this->structures as $structure) {
if ($structure['label'] && $structure['form_component'] && $structure['search']) {
if (isset($formComponents[$structure['form_component']])) {
$search = $search->append(
Str::of($formComponents[$structure['form_component']])
->replace(
[$this->label, $this->prop, $this->modelValue],
[$structure['label'], $structure['field'], sprintf('query.%s', $structure['field'])]
)
);
}
}
}
return $search->trim(PHP_EOL)->toString();
}
/**
* get list content;
*
* @return string
*/
protected function getTableContent(): string
{
$tableColumn = <<<HTML
<el-table-column prop="{prop}" label="{label}" />
HTML;
$table = Str::of('');
foreach ($this->structures as $structure) {
if ($structure['field'] && $structure['label'] && $structure['list']) {
$table = $table->append(
Str::of($tableColumn)->replace([$this->label, $this->prop], [$structure['label'], $structure['field']])
)->newLine();
}
}
return $table->trim(PHP_EOL)->toString();
}
/**
* form components
*
* @return array
*/
protected function formComponents(): array
{
$components = [];
foreach (File::glob(
$this->getFormItemStub()
) as $stub) {
$components[File::name($stub)] = File::get($stub);
}
return $components;
}
/**
* get formItem stub
*
* @return string
*/
protected function getFormItemStub(): string
{
return dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'
.DIRECTORY_SEPARATOR.'vue'.DIRECTORY_SEPARATOR
.'formItems'.DIRECTORY_SEPARATOR.'*.stub';
}
/**
* get table stub
*
* @return string
*/
protected function getTableStub(): string
{
return dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'
.DIRECTORY_SEPARATOR.'vue'.DIRECTORY_SEPARATOR.'table.stub';
}
/**
* get paginate stub content
*
* @return string
*/
protected function getPaginateStubContent(): string
{
return $this->hasPaginate ?
File::get(
dirname(__DIR__).DIRECTORY_SEPARATOR
.'stubs'.DIRECTORY_SEPARATOR.'vue'.
DIRECTORY_SEPARATOR.'paginate.stub'
)
: '';
}
/**
* get use List
* @return string
*/
protected function getUseList(): string
{
return $this->hasPaginate ?
'const { data, query, search, reset, changePage, changeLimit, loading } = useGetList(api)' :
'const { data, query, search, reset, loading } = useGetList(api)';
}
/**
* set structures
*
* @param array $structures
* @return $this
*/
public function setStructures(array $structures): static
{
$this->structures = $structures;
return $this;
}
}

View File

@@ -0,0 +1,276 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Catch\CatchAdmin;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Schema as SchemaFacade;
use Illuminate\Support\Str;
use Illuminate\Database\Eloquent\Model as EloquentModel;
class Model extends Creator
{
protected array $replace = [
'{uses}',
'{property}',
'{namespace}',
'{model}',
'{traits}',
'{table}',
'{fillable}',
'{searchable}',
'{fieldsInList}',
'{isPaginate}', '{form}'
];
protected array $structures;
protected bool $softDelete;
/**
* @param string $modelName
* @param string $tableName
* @param bool $isPaginate
*/
public function __construct(
protected string $modelName,
protected readonly string $tableName,
protected readonly bool $isPaginate
) {
$model = new class () extends EloquentModel {
use SoftDeletes;
};
$this->softDelete = in_array($model->getDeletedAtColumn(), SchemaFacade::getColumnListing($this->tableName));
}
/**
* get file
*
* @return string
*/
public function getFile(): string
{
// TODO: Implement getFile() method.
return CatchAdmin::getModuleModelPath($this->module).$this->getModelName().$this->ext;
}
/**
* get content
*
* @return string
*/
public function getContent(): string
{
$modelStub = File::get($this->getModelStub());
return Str::of($modelStub)->replace($this->replace, [$this->getUses(),
$this->getProperties(),
$this->getModelNamespace(),
$this->getModelName(),
$this->getTraits(),
$this->tableName,
$this->getFillable(),
$this->getSearchable(),
$this->getFieldsInList(),
$this->isPaginate(),
$this->getInForm()
])->toString();
}
/**
* get model namespace
*
* @return string
*/
public function getModelNamespace(): string
{
return Str::of(CatchAdmin::getModuleModelNamespace($this->module))->trim('\\')->append(';')->toString();
}
/**
* get model name
*
* @return string
*/
public function getModelName(): string
{
$modelName = Str::of($this->modelName);
if (! $modelName->length()) {
$modelName = Str::of($this->tableName)->camel();
}
return $modelName->ucfirst()->whenContains('Model', function ($value) {
return Str::of($value);
}, function ($value) {
return Str::of($value)->append('Model');
})->toString();
}
/**
* get uses
*
* @return string
*/
protected function getUses(): string
{
if (! $this->softDelete) {
return <<<Text
use Catch\Traits\DB\BaseOperate;
use Catch\Traits\DB\ScopeTrait;
use Catch\Traits\DB\Trans;
use Illuminate\Database\Eloquent\Model;
Text;
} else {
return <<<Text
use Catch\Base\CatchModel as Model;
Text;
}
}
/**
* get traits
*
* @return string
*/
protected function getTraits(): string
{
return $this->softDelete ? '' : 'use BaseOperate, Trans, ScopeTrait;';
}
/**
*
* @return string
*/
protected function getProperties(): string
{
$comment = Str::of('/**')->newLine();
foreach ($this->getTableColumns() as $column) {
$comment = $comment->append(sprintf(' * @property $%s', $column))->newLine();
}
return $comment->append('*/')->toString();
}
/**
* get fillable
*
* @return string
*/
protected function getFillable(): string
{
$fillable = Str::of('');
foreach ($this->getTableColumns() as $column) {
$fillable = $fillable->append(" '{$column}'")->append(',');
}
return $fillable->rtrim(',')->toString();
}
/**
*
* @return array
*/
protected function getTableColumns(): array
{
return getTableColumns($this->tableName);
}
/**
* get field in list
*
* @return string
*/
protected function getFieldsInList(): string
{
$str = Str::of('');
foreach ($this->structures as $structure) {
if ($structure['list']) {
$str = $str->append("'{$structure['field']}'")->append(',');
}
}
return $str->rtrim(',')->toString();
}
/**
* get field in list
*
* @return string
*/
protected function getInForm(): string
{
$str = Str::of('');
foreach ($this->structures as $structure) {
if ($structure['form']) {
$str = $str->append("'{$structure['field']}'")->append(',');
}
}
return $str->rtrim(',')->toString();
}
/**
* searchable
*
* @return string
*/
protected function getSearchable(): string
{
$searchable = Str::of('');
foreach ($this->structures as $structure) {
if ($structure['search'] && $structure['field'] && $structure['search_op']) {
$searchable = $searchable->append(sprintf("'%s' => '%s'", $structure['field'], $structure['search_op']))->append(',')->newLine();
}
}
return $searchable->toString();
}
/**
* @return string
*/
protected function isPaginate(): string
{
return $this->isPaginate ? '' : Str::of('protected bool $isPaginate = false;')->toString();
}
/**
* @param array $structures
* @return $this
*/
public function setStructures(array $structures): static
{
$this->structures = $structures;
return $this;
}
/**
* get stub
*
* @return string
*/
protected function getModelStub(): string
{
return dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'model.stub';
}
}

View File

@@ -0,0 +1,138 @@
<?php
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Catch\CatchAdmin;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class Request extends Creator
{
/**
* @var array
*/
protected array $structures;
/**
* @var array|string[]
*/
protected array $replace = ['{namespace}', '{request}', '{rule}'];
/**
* @param string $controller
*/
public function __construct(public readonly string $controller)
{
}
/**
* @return string
*/
public function getFile(): string
{
return CatchAdmin::getModuleRequestPath($this->module).$this->getRequestName().$this->ext;
}
/**
* get content
*
* @return string|bool
*/
public function getContent(): string|bool
{
$rule = $this->getRulesString();
if (! $rule) {
return false;
}
return Str::of(
File::get(dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'request.stub')
)->replace($this->replace, [$this->getNamespace(), $this->getRequestName(), $rule])->toString();
}
/**
* get namespace
*
* @return string
*/
protected function getNamespace(): string
{
return Str::of(CatchAdmin::getModuleRequestNamespace($this->module))->rtrim('\\')->append(';')->toString();
}
/**
* get request name
*
* @return ?string
*/
public function getRequestName(): ?string
{
if ($this->getRules()) {
return Str::of($this->controller)->remove('Controller')->append('Request')->ucfirst()->toString();
}
return null;
}
/**
* get rule
*
* @return string|bool
*/
public function getRulesString(): string|bool
{
$rules = $this->getRules();
if (! count($rules)) {
return false;
}
$rule = Str::of('');
foreach ($rules as $field => $validates) {
$rule = $rule->append("'{$field}'")
->append(' => ')
->append('\'')
->append(Arr::join($validates, '|'))
->append('\',')
->newLine();
}
return $rule->toString();
}
/**
* get rules
*
* @return array
*/
protected function getRules(): array
{
$rules = [];
foreach ($this->structures as $structure) {
if ($structure['field'] && count($structure['validates'])) {
$rules[$structure['field']] = $structure['validates'];
}
}
return $rules;
}
/**
* set structures
*
* @param array $structures
* @return $this
*/
public function setStructures(array $structures): static
{
$this->structures = $structures;
return $this;
}
}

View File

@@ -0,0 +1,123 @@
<?php
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Catch\CatchAdmin;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
/**
* Route
*/
class Route extends Creator
{
/**
* @param string $controller
*/
public function __construct(public readonly string $controller)
{
}
/**
* get file
*
* @return string
*/
public function getFile(): string
{
return CatchAdmin::getModuleRoutePath($this->module);
}
/**
* get content
*
* @return string
*/
public function getContent(): string
{
// route 主要添加两个点
// use Controller
// 添加路由
$route = Str::of('');
$originContent = File::get(CatchAdmin::getModuleRoutePath($this->module));
// 如果已经有 controller就不再追加路由
if (Str::of($originContent)->contains($this->getUserController())) {
return $originContent;
}
File::lines(CatchAdmin::getModuleRoutePath($this->module))
->each(function ($line) use (&$route) {
if (Str::of($line)->contains('Route::prefix')) {
$route = $route->trim(PHP_EOL)
->newLine()
->append($this->getUserController())
->append(';')
->newLine(2)
->append($line)
->newLine();
} else {
$route = $route->append($line)->newLine();
}
});
$apiResource = "Route::apiResource('{api}', {controller}::class);";
return Str::of($route->toString())->replace(
['{module}', '//next'],
[
lcfirst($this->module),
Str::of($apiResource)->replace(['{api}', '{controller}'], [$this->getApiString(), $this->getControllerName()])
->prepend("\t")
->prepend(PHP_EOL)
->newLine()->append("\t//next")]
)->toString();
}
/**
* get api
*
* @return string
*/
public function getApiString(): string
{
return Str::of($this->getControllerName())->remove('Controller')->snake('_')->replace('_', '/')->toString();
}
/**
* get api route
*
* @return string
*/
public function getApiRute(): string
{
return lcfirst($this->module).'/'.$this->getApiString();
}
/**
* use controller
*
* @return string
*/
protected function getUserController(): string
{
return 'use '.CatchAdmin::getModuleControllerNamespace($this->module).$this->getControllerName();
}
/**
* get controller name
*
* @return string
*/
protected function getControllerName(): string
{
return Str::of($this->controller)->whenContains('Controller', function ($value) {
return Str::of($value)->ucfirst();
}, function ($value) {
return Str::of($value)->append('Controller')->ucfirst();
})->toString();
}
}

View File

@@ -0,0 +1,317 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace Modules\Develop\Support\Generate\Create;
use Catch\CatchAdmin;
use Exception;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Schema as MigrationSchema;
/**
* schema
*/
class Schema extends Creator
{
/**
* @var bool
*/
protected bool $createdAt = true;
/**
* @var bool
*/
protected bool $updatedAt = true;
/**
* @var bool
*/
protected bool $deletedAt = true;
/**
* @var bool
*/
protected bool $creatorId = true;
/**
* @var array
*/
protected array $structures = [];
/**
* @param string $table
* @param string $engine
* @param string $charset
* @param string $collection
* @param string $comment
*/
public function __construct(
public readonly string $table,
public readonly string $engine,
public readonly string $charset,
public readonly string $collection,
public readonly string $comment
) {
}
/**
* create
*
* @return string|bool
* @throws Exception
*/
public function create(): string|bool
{
if (! count($this->structures)) {
return false;
}
if (MigrationSchema::hasTable($this->table)) {
throw new Exception(sprintf('[%s] 表已经存在', $this->table));
}
try {
$this->createTable();
if (MigrationSchema::hasTable($this->table)) {
return parent::create();
}
return false;
} catch (Exception $e) {
MigrationSchema::dropIfExists($this->table);
throw new Exception("由于{$e->getMessage()}, 表[{$this->table}]创建失败");
}
}
/**
* get file
*
* @return string
*/
public function getFile(): string
{
// TODO: Implement getFile() method.
return CatchAdmin::getModuleMigrationPath($this->module).date('Y_m_d_his_').'create_'.$this->table.'.php';
}
/**
* create table
*
* @throws Exception
*/
protected function createTable(): void
{
MigrationSchema::create($this->table, function (Blueprint $table) {
foreach ($this->structures as $structure) {
// if field && type hava value
if ($structure['type'] && $structure['field']) {
if ($structure['type'] == 'string') {
$column = $table->string($structure['field'], $structure['length'] ?: 255);
} elseif ($structure['type'] == 'char') {
$column = $table->char($structure['field'], $structure['length']);
} else {
$column = $table->{$structure['type']}($structure['field']);
}
$column = $column->nullable($structure['nullable']);
if ($structure['default']) {
$column = $column->default($structure['default']);
}
if ($structure['comment']) {
$column = $column->comment($structure['comment']);
}
if ($structure['unique']) {
$column->unique($structure['unique']);
}
}
}
if ($this->creatorId) {
$table->creatorId();
}
if ($this->createdAt) {
$table->createdAt();
}
if ($this->updatedAt) {
$table->updatedAt();
}
if ($this->deletedAt) {
$table->deletedAt();
}
$table->charset = $this->charset;
$table->engine = $this->engine;
$table->collation = $this->collection;
$table->comment($this->comment);
});
}
/**
* get migration content
*
* @return string
*/
public function getContent(): string
{
$stub = File::get($this->getStub());
return Str::of($stub)->replace(['{method}','{table}', '{content}'], ['create', $this->table, $this->getMigrationContent()])->toString();
}
/**
* get content
*
* @return string
*/
public function getMigrationContent(): string
{
$content = Str::of('');
foreach ($this->structures as $structure) {
$begin = Str::of('$table->');
$type = Str::of($structure['type']);
if ($type->exactly('string')) {
$begin = $begin->append(sprintf("string('%s'%s)", $structure['field'], $structure['length'] ? ", {$structure['length']}" : ''));
} elseif ($type->exactly('char')) {
$begin = $begin->append(sprintf("char('%s', %s)", $structure['field'], $structure['length']));
} elseif ($type->exactly('id')) {
$begin = $begin->append(Str::of($structure['field'])->exactly('id') ? 'id()' : sprintf("id('%s')", $structure['field']));
} else {
$begin = $begin->append(sprintf("%s('%s')", $structure['type'], $structure['field']));
}
$content = $content->append($begin)
->when($structure['nullable'], function ($str) {
return $str->append('->nullable()');
})
->when(isset($structure['default']), function ($str, $default) {
if (is_numeric($default)) {
return $str->append("->default({$default})");
}
if ($default) {
return $str->append("->default('{$default}')");
}
return $str;
})
->when($structure['unique'], function ($str) {
return $str->append("->unique()");
})
->when($structure['comment'], function ($str, $comment) {
return $str->append("->comment('{$comment}')");
})
->append(';')
->newLine();
}
if ($this->creatorId) {
$content = $content->append(Str::of('$table->')->append('creatorId();'))->newLine();
}
if ($this->createdAt) {
$content = $content->append(Str::of('$table->')->append('createdAt();'))->newLine();
}
if ($this->updatedAt) {
$content = $content->append(Str::of('$table->')->append('updatedAt();'))->newLine();
}
if ($this->deletedAt) {
$content = $content->append(Str::of('$table->')->append('deletedAt();'))->newLine();
}
return $content->newLine()
->append("\$table->engine='{$this->engine}'")
->append(';')
->newLine()
->append("\$table->comment('{$this->comment}')")
->append(';')
->toString();
}
/**
* @param bool $createdAt
* @return $this
*/
public function setCreatedAt(bool $createdAt): static
{
$this->createdAt = $createdAt;
return $this;
}
/**
* @param bool $updatedAt
* @return $this
*/
public function setUpdatedAt(bool $updatedAt): static
{
$this->updatedAt = $updatedAt;
return $this;
}
/**
* @param bool $deletedAt
* @return $this
*/
public function setDeletedAt(bool $deletedAt): static
{
$this->deletedAt = $deletedAt;
return $this;
}
/**
* @param bool $creatorId
* @return $this
*/
public function setCreatorId(bool $creatorId): static
{
$this->creatorId = $creatorId;
return $this;
}
/**
* @param array $structures
* @return $this
*/
public function setStructures(array $structures): static
{
$this->structures = $structures;
return $this;
}
/**
* get stub
*
* @return string
*/
protected function getStub(): string
{
return dirname(__DIR__).DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'migration.stub';
}
}

View File

@@ -0,0 +1,214 @@
<?php
// +----------------------------------------------------------------------
// | CatchAdmin [Just Like ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2021 https://catchadmin.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( https://github.com/JaguarJack/catchadmin-laravel/blob/master/LICENSE.md )
// +----------------------------------------------------------------------
// | Author: JaguarJack [ njphper@gmail.com ]
// +----------------------------------------------------------------------
namespace Modules\Develop\Support\Generate;
use Catch\Exceptions\FailedException;
use Exception;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Modules\Develop\Support\Generate\Create\Controller;
use Modules\Develop\Support\Generate\Create\FrontForm;
use Modules\Develop\Support\Generate\Create\FrontTable;
use Modules\Develop\Support\Generate\Create\Model;
use Modules\Develop\Support\Generate\Create\Request;
use Modules\Develop\Support\Generate\Create\Route;
/**
* @class Generator
*/
class Generator
{
/**
* @var array{module:string,controller:string,model:string,paginate: bool,schema: string}
*/
protected array $gen;
/**
* @var array{name: string,charset: string, collection: string,
* comment:string,created_at: bool, updated_at: bool, deleted_at: bool,
* creator_id: bool, updated_at: bool, engine: string}
*/
protected array $schema;
/**
* @var array
*/
protected array $structures;
/**
* @var array
*/
protected array $files = [];
/**
* this model name from controller
*
* @var string
*/
protected string $modelName;
/**
* this request name for controller
*
* @var ?string
*/
protected ?string $requestName;
/**
* generate
*
* @throws Exception
* @return bool
*/
public function generate(): bool
{
try {
$this->files[] = $this->createModel();
$this->files[] = $this->createRequest();
$this->files[] = $this->createController();
$this->files[] = $this->createFrontTable();
$this->files[] = $this->createFrontForm();
$this->files[] = $this->createRoute();
} catch (Exception $e) {
$this->rollback();
throw new FailedException($e->getMessage());
}
$this->files = [];
return true;
}
/**
* create route
*
* @throws FileNotFoundException
* @return bool|string
*/
public function createRoute(): bool|string
{
// 保存之前的 route 文件
$route = new Route($this->gen['controller']);
return $route->setModule($this->gen['module'])->create();
}
/**
* create font
*
* @throws FileNotFoundException
* @return bool|string|null
*/
public function createFrontTable(): bool|string|null
{
$table = new FrontTable($this->gen['controller'], $this->gen['paginate'], (new Route($this->gen['controller']))->setModule($this->gen['module'])->getApiRute());
return $table->setModule($this->gen['module'])->setStructures($this->structures)->create();
}
/**
* create font
*
* @throws FileNotFoundException
* @return bool|string|null
*/
public function createFrontForm(): bool|string|null
{
$form = new FrontForm($this->gen['controller']);
return $form->setModule($this->gen['module'])->setStructures($this->structures)->create();
}
/**
* create model
*
* @throws FileNotFoundException
* @return bool|string
*/
protected function createModel(): bool|string
{
$model = new Model($this->gen['model'], $this->gen['schema'], $this->gen['module']);
$this->modelName = $model->getModelName();
return $model->setModule($this->gen['module'])->setStructures($this->structures)->create();
}
/**
* create request
*
* @throws FileNotFoundException
* @return bool|string
*/
protected function createRequest(): bool|string
{
$request = new Request($this->gen['controller']);
$file = $request->setStructures($this->structures)->setModule($this->gen['module'])->create();
$this->requestName = $request->getRequestName();
return $file;
}
/**
* create controller
*
* @throws FileNotFoundException
* @return bool|string
*/
protected function createController(): bool|string
{
$controller = new Controller($this->gen['controller'], $this->modelName, $this->requestName);
return $controller->setModule($this->gen['module'])->create();
}
/**
* rollback
*
* @return void
*/
protected function rollback(): void
{
// delete controller & model & migration file
foreach ($this->files as $file) {
unlink($file);
}
// 回填之前的 route 文件
}
/**
* set params
*
* @param array $params
* @return $this
*/
public function setParams(array $params): Generator
{
$this->gen = $params['codeGen'];
$this->structures = $params['structures'];
return $this;
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Modules\Develop\Support\Generate;
use Catch\CatchAdmin;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Str;
class Module
{
public function __construct(
public string $module,
protected bool $controller,
protected bool $models,
protected bool $requests,
protected bool $database
) {
}
/**
* create
*
* @return void
*/
public function create(): void
{
if ($this->controller) {
CatchAdmin::getModuleControllerPath($this->module);
}
if ($this->models) {
CatchAdmin::getModuleModelPath($this->module);
}
if ($this->requests) {
CatchAdmin::getModuleRequestPath($this->module);
}
if ($this->database) {
CatchAdmin::getModuleMigrationPath($this->module);
CatchAdmin::getModuleSeederPath($this->module);
}
$this->createProvider();
$this->createRoute();
}
/**
* delete
*
* @return void
*/
public function delete(): void
{
}
/**
* create provider
*
* @return void
*/
protected function createProvider(): void
{
CatchAdmin::getModuleProviderPath($this->module);
File::put(
CatchAdmin::getModuleProviderPath($this->module).sprintf('%sServiceProvider.php', ucfirst($this->module)),
Str::of(
File::get(__DIR__.DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'provider.stub')
)->replace(['{Module}', '{module}'], [ucfirst($this->module), $this->module])
);
}
/**
* create route
*
* @return void
*/
protected function createRoute(): void
{
File::copy(__DIR__.DIRECTORY_SEPARATOR.'stubs'.DIRECTORY_SEPARATOR.'route.stub', CatchAdmin::getModuleRoutePath($this->module));
}
}

View File

@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace {namespace}
use Catch\Base\CatchController as Controller;
{uses}
class {controller} extends Controller
{
public function __construct(
protected readonly {model} $model
){}
/**
* @param Request $request
* @return mixed
*/
public function index(Request $request): mixed
{
return $this->model->getList();
}
public function store({request} $request)
{
return $this->model->storeBy($request->all());
}
public function show($id)
{
return $this->model->firstBy($id);
}
public function update($id, {request} $request)
{
return $this->model->updateBy($id, $request->all());
}
public function destroy($id)
{
return $this->model->deleteBy($id);
}
}

View File

@@ -0,0 +1,30 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::{method}('{table}', function (Blueprint $table) {
{content}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('{table}');
}
};

View File

@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace {namespace}
{uses}
{property}
class {model} extends Model
{
{traits}
protected $table = '{table}';
protected $fillable = [{fillable} ];
/**
* @var array
*/
protected array $fieldsInList = [{fieldsInList}];
/**
* @var array
*/
protected array $form = [{form}];
/**
* @var array
*/
public array $searchable = [
{searchable}
];
{isPaginate}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace Modules\{Module}\Providers;
use Catch\CatchAdmin;
use Catch\Providers\CatchModuleServiceProvider;
class {Module}ServiceProvider extends CatchModuleServiceProvider
{
/**
* route path
*
* @return string|array
*/
public function routePath(): string|array
{
// TODO: Implement path() method.
return CatchAdmin::getModuleRoutePath('{module}');
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace {namespace}
use Illuminate\Foundation\Http\FormRequest as Request;
class {request} extends Request
{
/**
* @return array
*/
public function rules(): array
{
return [
{rule}
];
}
/**
*
* @return array
*/
public function message(): array
{
return [];
}
}

View File

@@ -0,0 +1,7 @@
<?php
use Illuminate\Support\Facades\Route;
Route::prefix('{module}')->group(function(){
//next
});

View File

@@ -0,0 +1,38 @@
<template>
<el-form :model="formData" label-width="120px" ref="form" v-loading="loading" class="pr-4">
{formItems}
<div class="flex justify-end">
<el-button type="primary" @click="submitForm(form)">{{ $t('system.confirm') }}</el-button>
</div>
</el-form>
</template>
<script lang="ts" setup>
import { useCreate } from '/admin/composables/curd/useCreate'
import { useShow } from '/admin/composables/curd/useShow'
import { onMounted, watch } from 'vue'
const props = defineProps({
primary: String | Number,
api: String,
})
const emit = defineEmits(['close'])
const { formData, form, loading, submitForm, isClose } = useCreate(props.api, props.primary)
watch(isClose, function (value) {
if (value) {
emit('close')
}
})
onMounted(() => {
if (props.primary) {
useShow(props.api, props.primary).then(r => {
formData.value = r.data
})
}
})
</script>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{label}" prop="{prop}">
<el-cascader v-model="{model-value}" :options="options" />
</el-form-item>

View File

@@ -0,0 +1,9 @@
<el-form-item label="{label}" prop="{prop}">
<el-date-picker
v-model="{model-value}"
type="date"
name="{prop}"
placeholder="Pick a day"
clearable
/>
</el-form-item>

View File

@@ -0,0 +1,9 @@
<el-form-item label="{label}" prop="{prop}">
<el-date-picker
v-model="{model-value}"
type="datetime"
name="{prop}"
placeholder="Pick a day"
clearable
/>
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{label}" prop="{prop}">
<el-input-number v-model="{model-value}" name="{prop}" :min="1" />
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{label}" prop="{prop}">
<el-input v-model="{model-value}" name="{prop}" clearable />
</el-form-item>

View File

@@ -0,0 +1,5 @@
<el-form-item label="{label}" prop="{prop}">
<el-radio-group v-model="{model-value}">
<el-radio v-for="item in options" :key="item.value" :label="item.value" name="{prop}">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{label}" prop="{prop}">
<el-rate v-model="{model-value}" name="{prop}" clearable />
</el-form-item>

View File

@@ -0,0 +1,10 @@
<el-form-item label="{label}" prop="{prop}">
<el-select v-model="{model-value}" placeholder="请选择" clearable ${multiple}>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>

View File

@@ -0,0 +1,3 @@
<el-form-item label="{label}" prop="{prop}">
<el-switch v-model="{model-value}" name="{prop}" />
</el-form-item>

View File

@@ -0,0 +1,9 @@
<el-form-item label="{label}" prop="{prop}">
<el-tree-select
v-model="{model-value}"
:data="data"
check-strictly
multiple
show-checkbox
/>
</el-form-item>

View File

@@ -0,0 +1,8 @@
<el-form-item label="{label}" prop="{prop}">
<el-tree
:data="data"
show-checkbox
node-key="id"
/>
</el-form-item>

View File

@@ -0,0 +1,12 @@
<div class="pt-2 pb-2 flex justify-end">
<el-pagination
background
layout="total,sizes,prev,pager,next"
:current-page="query.page"
:page-size="query.limit"
@current-change="changePage"
@size-change="changeLimit"
:total="total"
:page-sizes="[1, 10, 20, 30, 50]"
/>
</div>

View File

@@ -0,0 +1,78 @@
<template>
<div>
<div class="w-full min-h-0 bg-white dark:bg-regal-dark pl-5 pt-5 pr-5 rounded-lg">
<el-form :inline="true">
{search}
<el-form-item>
<el-button type="primary" @click="search()">
<Icon name="magnifying-glass" class="w-4 mr-1 -ml-1" />
搜索
</el-button>
<el-button @click="reset()">
<Icon name="arrow-path" class="w-4 mr-1 -ml-1" />
重置
</el-button>
</el-form-item>
</el-form>
</div>
<div class="pl-2 pr-2 bg-white dark:bg-regal-dark rounded-lg mt-4">
<div class="pt-5 pl-2">
<Add @click="show(null)" />
</div>
<el-table :data="tableData" class="mt-3" v-loading="loading">
{table}
<el-table-column label="操作" width="200">
<template #default="scope">
<Update @click="show(scope.row.id)" />
<Destroy @click="destroy(api, scope.row.id)" />
</template>
</el-table-column>
</el-table>
{paginate}
</div>
<Dialog v-model="visible" :title="title" destroy-on-close>
<Create @close="close" :primary="id" :api="api" />
</Dialog>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref, watch } from 'vue'
import Create from './create.vue'
import { useGetList } from '/admin/composables/curd/useGetList'
import { useDestroy } from '/admin/composables/curd/useDestroy'
import { useEnabled } from '/admin/composables/curd/useEnabled'
import { t } from '/admin/support/helper'
const visible = ref<boolean>(false)
const id = ref(null)
const api = {api}
const title = ref<string>('');
{useList}
const { destroy, isDeleted } = useDestroy()
const { enabled } = useEnabled()
onMounted(() => search())
const tableData = computed(() => data.value?.data)
const total = computed(() => data.value?.total)
const close = () => {
visible.value = false
reset()
}
const show = primary => {
title.value = primary ? t('system.edit') : t('system.add')
id.value = primary
visible.value = true
}
watch(isDeleted, function (){
// change origin status
isDeleted.value = false
reset();
})
</script>