🚀 更新CRUD/CRUD可视化操作,新增支持可视化命令行
Extend the CURD generation functionality to support command line operations, supplementing the existing visual generation method. This update includes modifications to the admin interface, enabling the system to process both types of CURD generation commands effectively.
This commit is contained in:
@@ -10,6 +10,7 @@ use app\admin\service\annotation\NodeAnnotation;
|
||||
use app\Request;
|
||||
use think\db\exception\PDOException;
|
||||
use think\exception\FileException;
|
||||
use think\facade\Console;
|
||||
use think\facade\Db;
|
||||
use think\helper\Str;
|
||||
use think\response\Json;
|
||||
@@ -35,11 +36,12 @@ class CurdGenerate extends AdminController
|
||||
public function save(Request $request, string $type = ''): ?Json
|
||||
{
|
||||
if (!$request->isAjax()) $this->error();
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
switch ($type) {
|
||||
case "search":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
try {
|
||||
$list = Db::query("SHOW FULL COLUMNS FROM {$tb_prefix}{$tb_name}");
|
||||
$data = [];
|
||||
@@ -59,6 +61,10 @@ class CurdGenerate extends AdminController
|
||||
}
|
||||
break;
|
||||
case "add":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
$tb_fields = $request->param('tb_fields');
|
||||
$force = $request->post('force/d', 0);
|
||||
try {
|
||||
@@ -121,6 +127,10 @@ class CurdGenerate extends AdminController
|
||||
}
|
||||
break;
|
||||
case "delete":
|
||||
$tb_prefix = $request->param('tb_prefix/s', '');
|
||||
$tb_name = $request->param('tb_name/s', '');
|
||||
if (empty($tb_name)) $this->error('参数错误');
|
||||
|
||||
try {
|
||||
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
|
||||
$build = $build->render();
|
||||
@@ -132,6 +142,19 @@ class CurdGenerate extends AdminController
|
||||
return json(['code' => -1, 'msg' => $exception->getMessage()]);
|
||||
}
|
||||
break;
|
||||
case 'console':
|
||||
$command = $request->post('command', '');
|
||||
if (empty($command)) $this->error('请输入命令');
|
||||
$commandExp = explode(' ', $command);
|
||||
try {
|
||||
|
||||
$output = Console::call('curd', [...$commandExp]);
|
||||
}catch (\Throwable $exception) {
|
||||
$this->error($exception->getMessage() . $exception->getLine());
|
||||
}
|
||||
if (empty($output)) $this->error('设置错误');
|
||||
$this->success($output->fetch());
|
||||
break;
|
||||
default:
|
||||
$this->error('参数错误');
|
||||
break;
|
||||
|
||||
@@ -1125,6 +1125,7 @@ class BuildCurd
|
||||
// 'selectList' => $selectList,
|
||||
'selectArrays' => CommonTool::replaceArrayString(var_export($selectArrays, true)),
|
||||
]);
|
||||
|
||||
$this->fileList[$modelFile] = $modelValue;
|
||||
|
||||
// 关联模型
|
||||
@@ -1347,13 +1348,13 @@ class BuildCurd
|
||||
continue;
|
||||
}elseif (in_array($field, $this->switchFields)) {
|
||||
if (!empty($val['define'])) {
|
||||
$templateValue = "{field: '{$field}', search: 'select', selectList: {$field}List, title: '{$val['comment']}', templet: ea.table.switch}";
|
||||
$templateValue = "{field: '{$field}', search: 'select', selectList: notes?.{$field} || {}, title: '{$val['comment']}', templet: ea.table.switch}";
|
||||
}else {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.switch}";
|
||||
}
|
||||
}elseif (in_array($val['formType'], ['select', 'checkbox', 'radio', 'switch'])) {
|
||||
if (!empty($val['define'])) {
|
||||
$templateValue = "{field: '{$field}', search: 'select', selectList: {$field}List, title: '{$val['comment']}'}";
|
||||
$templateValue = "{field: '{$field}', search: 'select', selectList: notes?.{$field} || {}, title: '{$val['comment']}'}";
|
||||
}else {
|
||||
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
|
||||
}
|
||||
@@ -1528,12 +1529,6 @@ class BuildCurd
|
||||
|
||||
protected function formatNotesScript(): string
|
||||
{
|
||||
$array = [];
|
||||
foreach ($this->tableColumns as $key => $column) {
|
||||
if (empty($column['formType'])) continue;
|
||||
if (!in_array($column['formType'], ['select', 'switch', 'radio', 'checkbox'])) continue;
|
||||
$array[] = ' let ' . $key . 'List = JSON.parse(\'{$notes.' . $key . '|json_encode=256|raw}\');';
|
||||
}
|
||||
return implode(PHP_EOL, $array);
|
||||
return ' let notes = JSON.parse(\'{$notes|json_encode=256|raw}\');';
|
||||
}
|
||||
}
|
||||
@@ -5,104 +5,115 @@
|
||||
}
|
||||
</style>
|
||||
<div class="layuimini-container">
|
||||
<div class="layuimini-main" id="app">
|
||||
<div class="layuimini-main">
|
||||
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||
<div class="layui-tab" lay-filter="curd-hash">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this" lay-id="1">视图生成</li>
|
||||
<li lay-id="2">命令生成</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
|
||||
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
<form id="app-form" class="layui-form layuimini-form">
|
||||
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库表前缀</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="tb_prefix" class="layui-input" placeholder="请输入" value="{:env('DB_PREFIX','')}">
|
||||
<tip>可为空,为空则不带前缀</tip>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库表前缀</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="tb_prefix" class="layui-input" placeholder="请输入" value="{:env('DB_PREFIX','')}">
|
||||
<tip>可为空,为空则不带前缀</tip>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库表名字</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="tb_name" class="layui-input" lay-verify="required" placeholder="请输入:例如 test_goods" value="">
|
||||
<tip>数据库表名字 不包含数据库表前缀。</tip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-filter="search" lay-submit="system.CurdGenerate/save?type=search" data-refresh="false">查询</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tableShow layui-hide">
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
数据表:<span class="table-text"></span>
|
||||
</blockquote>
|
||||
<div class="layui-card-body">
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置忽略字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="ignore"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置下拉字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="select"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置单选字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="radio"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置多选字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="checkbox"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置单选图片字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="image"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置多选图片字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="images"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置日期(Y-m-d)字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="date"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置日期时间(Y-m-d H:i:s)字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="datetime"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置编辑器字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="editor"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
<div class="layui-btn-container">
|
||||
<form class="layui-form layuimini-form">
|
||||
<button type="button" class="layui-btn layui-bg-cyan" lay-filter="add" lay-submit="system.CurdGenerate/save?type=add">自动生成CURD</button>
|
||||
<button type="button" class="layui-btn layui-bg-red" lay-filter="delete" lay-submit="system.CurdGenerate/save?type=delete">删除CURD对应的文件</button>
|
||||
</form>
|
||||
<div class="file-list layui-elem-quote">还未生成任何文件</div>
|
||||
</div>
|
||||
<table id="currentTable" class="layui-table" lay-filter="currentTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">数据库表名字</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="tb_name" class="layui-input" lay-verify="required" placeholder="请输入:例如 test_goods" value="">
|
||||
<tip>数据库表名字 不包含数据库表前缀。</tip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hr-line"></div>
|
||||
<div class="layui-form-item text-center">
|
||||
<button type="button" class="layui-btn layui-btn-normal layui-btn-sm" lay-filter="search" lay-submit="system.CurdGenerate/save?type=search" data-refresh="false">查询</button>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="tableShow layui-hide">
|
||||
<blockquote class="layui-elem-quote layui-quote-nm">
|
||||
数据表:<span class="table-text"></span>
|
||||
</blockquote>
|
||||
<div class="layui-card-body">
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置忽略字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="ignore"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置下拉字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="select"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置单选字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="radio"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置多选字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="checkbox"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置单选图片字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="image"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置多选图片字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="images"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置日期(Y-m-d)字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="date"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置日期时间(Y-m-d H:i:s)字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="datetime"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend class="layui-font-16">设置编辑器字段</legend>
|
||||
<div class="layui-field-box">
|
||||
<div class="table_fields layui-form" data-name="editor"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="layui-tab-item"></div>
|
||||
</div>
|
||||
<div class="layui-btn-container">
|
||||
<form class="layui-form layuimini-form">
|
||||
<button type="button" class="layui-btn layui-bg-cyan" lay-filter="add" lay-submit="system.CurdGenerate/save?type=add">自动生成CURD</button>
|
||||
<button type="button" class="layui-btn layui-bg-red" lay-filter="delete" lay-submit="system.CurdGenerate/save?type=delete">删除CURD对应的文件</button>
|
||||
</form>
|
||||
<div class="file-list layui-elem-quote">还未生成任何文件</div>
|
||||
</div>
|
||||
<table id="currentTable" class="layui-table" lay-filter="currentTable"></table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -47,9 +47,6 @@ class Curd extends Command
|
||||
protected function execute(Input $input, Output $output)
|
||||
{
|
||||
|
||||
CliEcho::warn('请优先使用系统自带的 CURD/CRUD 可视化生成功能(关联功能增加中~),命令行 CURD/CRUD 功能将逐步下线!');
|
||||
CliEcho::notice(PHP_EOL);
|
||||
|
||||
$table = $input->getOption('table');
|
||||
$controllerFilename = $input->getOption('controllerFilename');
|
||||
$modelFilename = $input->getOption('modelFilename');
|
||||
@@ -89,7 +86,10 @@ class Curd extends Command
|
||||
}
|
||||
|
||||
if (empty($table)) {
|
||||
CliEcho::error('请设置主表');
|
||||
if (PHP_SAPI == 'cli')
|
||||
CliEcho::error('请设置主表');
|
||||
else
|
||||
$output->writeln('请设置主表');
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -123,41 +123,58 @@ class Curd extends Command
|
||||
if (!$delete) {
|
||||
$result = $build->create();
|
||||
if ($force) {
|
||||
if (PHP_SAPI == 'cli') {
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
foreach ($fileList as $key => $val) {
|
||||
$output->info($key);
|
||||
}
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
$output->info("确定强制生成上方所有文件? 如果文件存在会直接覆盖。 请输入 'yes' 按回车键继续操作: ");
|
||||
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||
if (trim($line) != 'yes') {
|
||||
throw new Exception("取消文件CURD生成操作");
|
||||
}
|
||||
CliEcho::success('自动生成CURD成功');
|
||||
}else {
|
||||
$output->writeln('自动生成CURD成功');
|
||||
}
|
||||
}
|
||||
}else {
|
||||
if (PHP_SAPI == 'cli') {
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
foreach ($fileList as $key => $val) {
|
||||
$output->info($key);
|
||||
}
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
$output->info("确定强制生成上方所有文件? 如果文件存在会直接覆盖。 请输入 'yes' 按回车键继续操作: ");
|
||||
$output->info("确定删除上方所有文件? 请输入 'yes' 按回车键继续操作: ");
|
||||
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||
if (trim($line) != 'yes') {
|
||||
throw new Exception("取消文件CURD生成操作");
|
||||
throw new Exception("取消删除文件操作");
|
||||
}
|
||||
$result = $build->delete();
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
CliEcho::success('删除自动生成CURD文件成功');
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
foreach ($result as $vo) {
|
||||
CliEcho::success($vo);
|
||||
}
|
||||
}else {
|
||||
$result = $build->delete();
|
||||
$output->writeln('>>>>>>>>>>>>>>>');
|
||||
$output->writeln('删除自动生成CURD文件成功');
|
||||
$output->writeln('>>>>>>>>>>>>>>>');
|
||||
foreach ($result as $vo) {
|
||||
$output->writeln($vo);
|
||||
}
|
||||
}
|
||||
CliEcho::success('自动生成CURD成功');
|
||||
}else {
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
foreach ($fileList as $key => $val) {
|
||||
$output->info($key);
|
||||
}
|
||||
$output->info(">>>>>>>>>>>>>>>");
|
||||
$output->info("确定删除上方所有文件? 请输入 'yes' 按回车键继续操作: ");
|
||||
$line = fgets(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'));
|
||||
if (trim($line) != 'yes') {
|
||||
throw new Exception("取消删除文件操作");
|
||||
}
|
||||
$result = $build->delete();
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
CliEcho::success('删除自动生成CURD文件成功');
|
||||
}
|
||||
CliEcho::success('>>>>>>>>>>>>>>>');
|
||||
foreach ($result as $vo) {
|
||||
CliEcho::success($vo);
|
||||
}
|
||||
}catch (\Exception $e) {
|
||||
CliEcho::error($e->getMessage());
|
||||
return false;
|
||||
if (PHP_SAPI == 'cli')
|
||||
CliEcho::error($e->getMessage());
|
||||
else
|
||||
$output->writeln($e->getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,63 @@ define(["jquery", "easy-admin", "miniTab"], function ($, ea, miniTab) {
|
||||
|
||||
return {
|
||||
index: function () {
|
||||
|
||||
let element = layui.element;
|
||||
element.on('tab(curd-hash)', function (obj) {
|
||||
let id = obj.id
|
||||
let _html = `
|
||||
<div style="padding: 50px 25px;">
|
||||
<fieldset class="layui-elem-field">
|
||||
<legend>提示</legend>
|
||||
<div class="layui-field-box">
|
||||
<p><a class="layui-font-blue" target="_blank" rel="nofollow" href="https://edocs.easyadmin8.top/curd/command.html">命令可查询文档</a></p>
|
||||
</div>
|
||||
</fieldset>
|
||||
<form class="layui-form layui-form-pane" action="">
|
||||
<div class="layui-form-item">
|
||||
<div class="layui-input-group" style="width: 100%;">
|
||||
<div class="layui-input-split layui-input-prefix" style="width: 100px;">
|
||||
php think curd
|
||||
</div>
|
||||
<input type="text" class="layui-input" name="command" placeholder="在这里输入命令参数" lay-verify="required"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<button class="layui-btn layui-btn-fluid layui-bg-cyan" type="button" lay-submit="system.CurdGenerate/save?type=console" lay-filter="curd-console-submit">一键执行</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
`
|
||||
if (id == '2') {
|
||||
layer.open({
|
||||
title: '命令行一键生成 CRUD/CRUD',
|
||||
type: 1,
|
||||
shade: 0.3,
|
||||
shadeClose: false,
|
||||
area: ['42%', 'auto'],
|
||||
content: _html,
|
||||
success: function () {
|
||||
form.on('submit(curd-console-submit)', function (data) {
|
||||
let field = data.field
|
||||
let url = $(this).attr('lay-submit')
|
||||
let options = {url: ea.url(url), data: field}
|
||||
ea.msg.confirm('确认执行该操作?<br>如果命令行中存在强制覆盖或者删除将会马上执行!', function () {
|
||||
ea.request.post(options, function (rs) {
|
||||
let msg = rs.msg || '未知~'
|
||||
layer.msg(msg.replace(/\n/g, '<br>'), {shade: 0.3, shadeClose: true})
|
||||
let code = rs?.code || '-1'
|
||||
if (code != '1') return
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
end: function () {
|
||||
element.tabChange('curd-hash', '1');
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
miniTab.listen();
|
||||
let createStatus = false
|
||||
let tb_prefix
|
||||
|
||||
Reference in New Issue
Block a user