Skip to content

Commit

Permalink
代码生成V1~ 暂无字典、交互生成。
Browse files Browse the repository at this point in the history
 php artisan generator Permission Admin
  • Loading branch information
pleaseyang committed Mar 9, 2022
1 parent fae1572 commit 5c07af7
Show file tree
Hide file tree
Showing 12 changed files with 989 additions and 0 deletions.
256 changes: 256 additions & 0 deletions app/Console/Commands/Generator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ZipArchive;

class Generator extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'generator {model : Model名称} {module : 模块名称}';

/**
* 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 void
*/
public function handle()
{
$disk = Storage::disk('codes');
$disk->deleteDirectory('php');
$disk->deleteDirectory('js');
$disk->delete('generator.zip');
$model = $this->argument('model');
$module = $this->argument('module');
$dbName = Str::snake(Str::pluralStudly($model));
$singular = Str::singular($dbName);

// Controller
$controller = str_replace([
'{{model}}', '{{module}}'
], [
$model, $module
], $this->getStub('Controller'));
$controllerPath = "php/app/Http/Controllers/$module/{$model}Controller.php";
Storage::disk('codes')->put($controllerPath, $controller);

$api = str_replace([
'{{model}}', '{{module}}', '{{snake}}', '{{singular}}'
], [
$model, $module, $dbName, $singular
], $this->getStub('api'));
$apiPath = "php/routes/api.php";
Storage::disk('codes')->put($apiPath, $api);

// Model
$dbColumns = DB::select(sprintf("select `COLUMN_NAME` as name ,DATA_TYPE as type,COLUMN_COMMENT as comment, IS_NULLABLE as is_null, COLUMN_KEY as `key` from information_schema.columns where TABLE_NAME='$dbName' and table_schema = '%s';", config('database.connections.mysql.database')));

$fillable = [];
$unGeneratorColumns = ['id', 'created_at', 'updated_at'];
$where = [];
foreach ($dbColumns as $dbColumn) {
if (!in_array($dbColumn->name, $unGeneratorColumns)) {
$fillable[] = "'$dbColumn->name'";
}
if (in_array($dbColumn->type, ['bigint', 'int', 'tinyint'])) {
$text = 'when(isset($validated[\''.$dbColumn->name.'\']) && is_numeric($validated[\''.$dbColumn->name.'\']), function (Builder $query) use ($validated): Builder {
return $query->where(\''.$dbName.'.'.$dbColumn->name.'\', $validated[\''.$dbColumn->name.'\']);
})';
$where[] = $text;
}
if (in_array($dbColumn->type, ['varchar'])) {
$text = 'when($validated[\''.$dbColumn->name.'\'] ?? null, function (Builder $query) use ($validated): Builder {
return $query->where(\''.$dbName.'.'.$dbColumn->name.'\', \'like\', \'%\' . $validated[\''.$dbColumn->name.'\'] . \'%\');
})';
$where[] = $text;
}
}
$fillable = implode(', ', $fillable);
$where = implode('->', $where);
$modelStub = str_replace([
'{{model}}', '{{dbName}}', '{{fillable}}', '{{where}}'
], [
$model, $dbName, $fillable, $where
], $this->getStub('Model'));
$modelPath = "php/app/Models/{$model}.php";
Storage::disk('codes')->put($modelPath, $modelStub);

// Request
$get = [];
$create = [];
$update = [];
foreach ($dbColumns as $dbColumn) {
$type = 'string';
if (in_array($dbColumn->type, ['bigint', 'int', 'tinyint'])) {
$type = 'numeric';
}
if (in_array($dbColumn->type, ['timestamp', 'datetime'])) {
$type = 'date_format:Y-m-d H:i:s';
}
$required = $dbColumn->is_null === 'NO' ? 'required': 'nullable';
$unique = $dbColumn->key === 'UNI' ? "Rule::unique('$dbName')" : '';
if (in_array($dbColumn->type, ['bigint', 'int', 'tinyint', 'varchar'])) {
$get[] = "'{$dbColumn->name}' => ['nullable', 'string',]";
}
if (!in_array($dbColumn->name, $unGeneratorColumns)) {
$create[] = "'{$dbColumn->name}' => ['$required', '$type', $unique]";
if ($unique) {
$uniqueText = $unique . '->ignore($this->post(\'id\'))';
} else {
$uniqueText = '';
}
$update[] = '\''.$dbColumn->name.'\' => [\'' . $required . '\', \'' . $type .'\', ' . $uniqueText . ']';
}
}
$update[] = "'id' => ['required', 'numeric', 'exists:{$dbName}',]";

$attributes = [];
foreach ($dbColumns as $dbColumn) {
$attributes[] = "'{$dbColumn->name}' => '{$dbColumn->comment}',";
}

$attributes = implode("\n ", $attributes);
$get = implode(",\n ", $get);
$create = implode(",\n ", $create);
$update = implode(",\n ", $update);
$id = "'id' => ['required', 'integer', Rule::exists('{$dbName}', 'id'),],";
$getRequest = str_replace([
'{{model}}', '{{module}}', '{{rules}}', '{{attributes}}'
], [
$model, $module, $get, $attributes
], $this->getStub('GetListRequest'));
$getRequestPath = "php/app/Http/Requests/$module/{$model}/GetListRequest.php";
Storage::disk('codes')->put($getRequestPath, $getRequest);

$createRequest = str_replace([
'{{model}}', '{{module}}', '{{rules}}', '{{attributes}}'
], [
$model, $module, $create, $attributes
], $this->getStub('CreateRequest'));
$createRequestPath = "php/app/Http/Requests/$module/{$model}/CreateRequest.php";
Storage::disk('codes')->put($createRequestPath, $createRequest);

$updateRequest = str_replace([
'{{model}}', '{{module}}', '{{rules}}', '{{attributes}}'
], [
$model, $module, $update, $attributes
], $this->getStub('UpdateRequest'));
$updateRequestPath = "php/app/Http/Requests/$module/{$model}/UpdateRequest.php";
Storage::disk('codes')->put($updateRequestPath, $updateRequest);

$idRequest = str_replace([
'{{model}}', '{{module}}', '{{rules}}', '{{attributes}}'
], [
$model, $module, $id, $attributes
], $this->getStub('IdRequest'));
$idRequestPath = "php/app/Http/Requests/$module/{$model}/IdRequest.php";
Storage::disk('codes')->put($idRequestPath, $idRequest);


// js

// api js
$apiJs = str_replace([
'{{snake}}', '{{singular}}'
], [
$dbName, $singular
], $this->getStub('apijs'));
$apiJsPath = "js/src/api/$singular.js";
Storage::disk('codes')->put($apiJsPath, $apiJs);

$search = [];
$table = [];
$create = [];
$update = [];
$form = [];
foreach ($dbColumns as $dbColumn) {
if (!in_array($dbColumn->name, $unGeneratorColumns)) {
$comment = $dbColumn->comment === '' ? $dbColumn->name : $dbColumn->comment;
if (in_array($dbColumn->type, ['varchar'])) {
$search[] = '<el-form-item label="'.$comment.'" prop="'.$dbColumn->name.'">
<el-input v-model="formInline.'.$dbColumn->name.'" placeholder="'.$comment.'" />
</el-form-item>';
}

$table[] = '<el-table-column prop="'.$dbColumn->name.'" label="'.$comment.'" sortable />';

$create[] = '<el-form-item label="'.$comment.'" prop="'.$dbColumn->name.'" :error="createError.'.$dbColumn->name.' ? createError.'.$dbColumn->name.'[0] : \'\'">
<el-input v-model="createForm.'.$dbColumn->name.'" />
</el-form-item>';

$update[] = '<el-form-item label="'.$comment.'" prop="'.$dbColumn->name.'" :error="updateError.'.$dbColumn->name.' ? updateError.'.$dbColumn->name.'[0] : \'\'">
<el-input v-model="updateForm.'.$dbColumn->name.'" />
</el-form-item>';

$form[] = "$dbColumn->name: ''";
}
}
$search = implode("\n ", $search);
$table = implode("\n ", $table);
$create = implode("\n ", $create);
$update = implode("\n ", $update);
$form = implode(",\n ", $form);
$vue = str_replace([
'{{search}}', '{{table}}', '{{create}}', '{{update}}', '{{snake}}', '{{singular}}', '{{form}}'
], [
$search, $table, $create, $update, $dbName, $singular, $form
], $this->getStub('vue'));
$vuePath = "js/src/views/$singular/$dbName.vue";
Storage::disk('codes')->put($vuePath, $vue);

$zip = new ZipArchive();
$zipPath = storage_path("codes/generator.zip");
$zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE); //打开压缩包
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator(storage_path("codes")),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach ($files as $file) {
if (!$file->isDir()) {
$filePath = $file->getRealPath();
if (basename($filePath) !== '.gitignore') {
$relativePath = substr($filePath, strlen(storage_path("codes")) + 1);
$zip->addFile($filePath, $relativePath);
}
}
}
$zip->close();
$disk->deleteDirectory('php');
$disk->deleteDirectory('js');

exec("explorer " . storage_path("codes"));
}

private function getStub(string $type): string
{
return file_get_contents(resource_path('stubs/' . $type . '.stub'));
}
}
5 changes: 5 additions & 0 deletions config/filesystems.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@
'root' => storage_path('logs'),
],

'codes' => [
'driver' => 'local',
'root' => storage_path('codes'),
],

'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
Expand Down
116 changes: 116 additions & 0 deletions resources/stubs/Controller.stub
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<?php

namespace App\Http\Controllers\{{module}};

use App\Http\Controllers\Controller;
use App\Http\Requests\{{module}}\{{model}}\GetListRequest;
use App\Http\Requests\{{module}}\{{model}}\IdRequest;
use App\Http\Requests\{{module}}\{{model}}\CreateRequest;
use App\Http\Requests\{{module}}\{{model}}\UpdateRequest;
use App\Http\Response\ApiCode;
use App\Models\{{model}};
use MarcinOrlowski\ResponseBuilder\ResponseBuilder;
use Symfony\Component\HttpFoundation\Response;
use Exception;

class {{model}}Controller extends Controller
{
/**
* 列表
*
* @param GetListRequest $request
* @return Response
*/
public function list(GetListRequest $request): Response
{
$validated = $request->validated();
return ResponseBuilder::asSuccess(ApiCode::HTTP_OK)
->withHttpCode(ApiCode::HTTP_OK)
->withData({{model}}::getList($validated))
->withMessage(__('message.common.search.success'))
->build();
}

/**
* 详情
*
* @param IdRequest $request
* @return Response
*/
public function info(IdRequest $request): Response
{
$validated = $request->validated();
$model = {{model}}::find($validated['id']);
return ResponseBuilder::asSuccess(ApiCode::HTTP_OK)
->withHttpCode(ApiCode::HTTP_OK)
->withData($model)
->withMessage(__('message.common.search.success'))
->build();
}

/**
* 添加
*
* @param CreateRequest $request
* @return Response
*/
public function create(CreateRequest $request): Response
{
$validated = $request->validated();
$model = {{model}}::create($validated);
return ResponseBuilder::asSuccess(ApiCode::HTTP_OK)
->withHttpCode(ApiCode::HTTP_OK)
->withData($model)
->withMessage(__('message.common.create.success'))
->build();
}

/**
* 编辑
*
* @param UpdateRequest $request
* @return Response
*/
public function update(UpdateRequest $request): Response
{
$validated = $request->validated();
$model = {{model}}::find($validated['id']);
if ($model) {
$model->update($validated);
return ResponseBuilder::asSuccess(ApiCode::HTTP_OK)
->withHttpCode(ApiCode::HTTP_OK)
->withData($model)
->withMessage(__('message.common.update.success'))
->build();
}
return ResponseBuilder::asError(ApiCode::HTTP_BAD_REQUEST)
->withHttpCode(ApiCode::HTTP_BAD_REQUEST)
->withMessage(__('message.common.update.fail'))
->build();
}

/**
* 删除
*
* @param IdRequest $request
* @return Response
* @throws Exception
*/
public function delete(IdRequest $request): Response
{
$validated = $request->validated();
$model = {{model}}::find($validated['id']);
try {
$model->delete();
return ResponseBuilder::asSuccess(ApiCode::HTTP_OK)
->withHttpCode(ApiCode::HTTP_OK)
->withMessage(__('message.common.delete.success'))
->build();
} catch (Exception $e) {
return ResponseBuilder::asError(ApiCode::HTTP_BAD_REQUEST)
->withHttpCode(ApiCode::HTTP_BAD_REQUEST)
->withMessage($e->getMessage())
->build();
}
}
}
Loading

0 comments on commit 5c07af7

Please sign in to comment.