...
 
Commits (15)
    https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/2d6331cad073713c4ac57e2fe94c05aee2e04133 简化Textarea写法 2023-11-19T11:16:35+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/84f21eb285ff43b45240ef18fabcace8e4a83baf 编辑器兼容curd自动生成 2023-11-20T13:07:01+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/0e6875eccb509debe6fda10563d057f77593d35e 安装步骤密码限制 2023-11-22T14:18:11+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/f5e93d00f1642ecbc2d2360c5235d81ecbc3e009 Update public.css 2023-11-22T17:07:31+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/5e3067bdfe38ef285d0b0890070ecf056826a637 Layui-v2.9.0 2023-11-30T13:24:05+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/7ae5e0555264e48fc9636b5f192c573b82546e80 CURD可视化操作 2023-12-09T23:52:22+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/27e174ac8f2453a234018fd5a34cdb3edb42afcf Update install.sql 2023-12-09T23:55:04+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/5dca3f98e6c95b5c9ef096bb0a6d0bfa30b123ec Update Node.php 2023-12-10T00:11:26+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/84d731ef0ebac1911854cc9ded263e690aef7d7e Update install.sql 2023-12-10T00:11:30+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/350d63351bc00f180133554a84da7b0ed53563d1 Delete index.blade.php 2023-12-10T00:12:59+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/cc4b1930766969fee457e0db32ff00e5ce1e8114 Create index.blade.php 2023-12-10T00:13:22+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/3fab15b8e95d65baabbfa5e05de1033a0056db95 Update add.blade.php 2024-01-06T10:57:36+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/72e5b054f069337bb43e5b977d24f656e5d85dd2 Update index.blade.php 2024-01-06T11:09:41+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/b15665de6f901921b25452e2eff0f8ca17a4d84f Update easy-admin.js 2024-01-06T11:09:45+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com https://gitcode.net/wolfcode/EasyAdmin8-Laravel/-/commit/6c423c06203fd72efdd5688d7cb9c68d6010c0f3 Update CurdGenerateController.php 2024-01-06T11:09:47+08:00 wolfcode 37436228+wolf-leo@users.noreply.github.com
......@@ -144,4 +144,18 @@ if (!function_exists('updateFields')) {
return $row->save();
}
/**
* @param string $detail
* @param string $name
* @param string $placeholder
* @return string
*/
function editor_textarea(string $detail, string $name = 'desc', string $placeholder = '请输入'): string
{
$editor_type = sysconfig('site', 'editor_type');
return match ($editor_type) {
'ckeditor' => "<textarea name='{$name}' rows='20' class='layui-textarea editor' placeholder='{$placeholder}'>{$detail}</textarea>",
default => "<script type='text/plain' id='{$name}' name='{$name}' class='editor' data-content='{$detail}'></script>",
};
}
}
<?php
namespace App\Http\Controllers\admin\system;
use App\Http\Controllers\common\AdminController;
use App\Http\Services\annotation\NodeAnnotation;
use App\Http\Services\annotation\ControllerAnnotation;
use App\Http\Services\curd\BuildCurd;
use App\Http\Services\curd\exceptions\FileException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\View\View;
/**
* @ControllerAnnotation(title="CURD可视化管理")
*/
class CurdGenerateController extends AdminController
{
/**
* @NodeAnnotation(title="列表")
*/
public function index(): View
{
return $this->fetch();
}
/**
* @NodeAnnotation(title="列表")
*/
public function save(): Response|JsonResponse|View
{
if (!request()->ajax()) return $this->error();
$type = request()->input('type', '');
$tb_prefix = request()->input('tb_prefix', '');
$tb_name = request()->input('tb_name', '');
if (empty($tb_name)) return $this->error('参数错误');
switch ($type) {
case "search":
try {
$list = DB::select("show full columns from {$tb_prefix}{$tb_name}");
$data = [];
foreach ($list as $value) {
$data[] = [
'name' => $value->Field,
'type' => $value->Type,
'key' => $value->Key,
'extra' => $value->Extra,
'null' => $value->Null,
'desc' => $value->Comment,
];
}
return $this->success('查询成功', compact('data', 'list'));
} catch (\PDOException|\Exception $exception) {
return $this->error($exception->getMessage());
}
break;
case "add":
$force = (int)request()->post('force', 0);
try {
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
$build->setForce($force); // 强制覆盖
$build = $build->render();
$fileList = $build->getFileList();
if (empty($fileList)) return $this->error('这里什么都没有');
$result = $build->create();
$_file = $result[0] ?? '';
$link = '';
if (!empty($_file)) {
$_fileExp = explode(DIRECTORY_SEPARATOR, $_file);
$_fileExp_last = array_slice($_fileExp, -2);
$link = '/' . env('EASYADMIN.ADMIN', 'admin') . '/' . $_fileExp_last[0] . '.' . Str::snake(explode('Controller.php', end($_fileExp_last))[0] ?? '') . '/index';
}
return $this->success('生成成功', compact('result', 'link'));
} catch (FileException $exception) {
return json(['code' => -1, 'msg' => $exception->getMessage(), '__token__' => csrf_token()]);
}
break;
case "delete":
try {
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
$build = $build->render();
$fileList = $build->getFileList();
if (empty($fileList)) return $this->error('这里什么都没有');
$result = $build->delete();
return $this->success('删除自动生成CURD文件成功', compact('result'));
} catch (FileException $exception) {
return json(['code' => -1, 'msg' => $exception->getMessage(), '__token__' => csrf_token()]);
}
break;
default:
return $this->error('参数错误');
break;
}
}
}
......@@ -138,8 +138,8 @@ class Node
}
// 根目录下的文件
$className = str_replace('.php', '', $file);
$controllerFormat = str_replace('\\', '.', $middleDir) . CommonTool::humpToLine(lcfirst($className));
$controllerFormat = str_replace('_controller', '', $controllerFormat);
$controllerFormat = str_replace('\\', '.', $middleDir) . lcfirst($className);
$controllerFormat = str_replace('Controller', '', $controllerFormat);
$list[$controllerFormat] = "{$this->baseNamespace}\\{$middleDir}" . $className;
}
}
......
......@@ -239,6 +239,12 @@ class BuildCurd
return $this;
}
public function setTablePrefix($prefix): static
{
$this->tablePrefix = $prefix;
return $this;
}
/**
* 设置主表
* @param $table
......@@ -871,7 +877,7 @@ class BuildCurd
}
// 判断富文本
if (in_array($field, $this->editorFields)) {
if (in_array($field, $this->editorFields) || in_array($val['type'], ['text', 'tinytext', 'mediumtext', 'longtext'])) {
$this->tableColumns[$field]['formType'] = 'editor';
continue;
}
......@@ -939,7 +945,7 @@ class BuildCurd
}
// 判断富文本
if (in_array($field, $this->editorFields)) {
if (in_array($field, $this->editorFields) || in_array($val['type'], ['text', 'tinytext', 'mediumtext', 'longtext'])) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'editor';
continue;
}
......@@ -1059,12 +1065,15 @@ class BuildCurd
$extendNamespace = '\\' . implode('\\', $extendNamespaceArray);
}
$samePrefix = $this->tablePrefix == config('database.connections.mysql.prefix');
$modelTemplate = $samePrefix ? 'model' : 'model_table';
$modelValue = CommonTool::replaceTemplate(
$this->getTemplate("model{$this->DS}model"),
$this->getTemplate("model{$this->DS}{$modelTemplate}"),
[
'modelName' => $this->modelName,
'modelNamespace' => "App\Models{$extendNamespace}",
'table' => $this->table,
'prefix_table' => $samePrefix ? "" : $this->tablePrefix,
'deleteTime' => $this->delete ? '"delete_time"' : 'false',
'relationList' => $relationList,
'selectList' => $selectList,
......@@ -1134,6 +1143,12 @@ class BuildCurd
$templateFile = "view{$this->DS}module{$this->DS}input";
$define = '';
// 根据formType去获取具体模板
if ($val['formType'] == 'editor') {
$templateFile = "view{$this->DS}module{$this->DS}editor";
$val['default'] = '""';
}
$addFormList .= CommonTool::replaceTemplate(
$this->getTemplate($templateFile),
[
......@@ -1162,9 +1177,14 @@ class BuildCurd
}
$templateFile = "view{$this->DS}module{$this->DS}input";
$define = '';
$value = '{{$row[\'' . $field . '\']}}';
$define = '';
$value = '{{$row[\'' . $field . '\']}}';
// 根据formType去获取具体模板
if ($val['formType'] == 'editor') {
$templateFile = "view{$this->DS}module{$this->DS}editor";
$value = '$row["' . $field . '"]';
}
$editFormList .= CommonTool::replaceTemplate(
$this->getTemplate($templateFile),
......
<?php
namespace {{modelNamespace}};
class {{modelName}} extends BaseModel
{
public function getTable(): string
{
$this->getConnection()->setTablePrefix('{{prefix_table}}');
$this->setTable('{{table}}');
return parent::getTable();
}
}
......@@ -2,6 +2,6 @@
<div class="layui-form-item">
<label class="layui-form-label">{{comment}}</label>
<div class="layui-input-block">
<textarea name="{{field}}" rows="20" class="layui-textarea editor" {{comment}} placeholder="请输入{{comment}}">{{value}}</textarea>
{!! editor_textarea({{value}},"{{field}}","{{comment}}") !!}
</div>
</div>
\ No newline at end of file
</div>
......@@ -323,6 +323,8 @@ INSERT INTO `ea_system_menu`
VALUES ('252', '228', '快捷入口', 'fa fa-list', 'system.quick/index', '', '_self', '0', '1', '', '1589623683', '1589623683', null);
INSERT INTO `ea_system_menu`
VALUES ('253', '228', '日志管理', 'fa fa-connectdevelop', 'system.log/index', '', '_self', '0', '1', '', '1589623684', '1589623684', null);
INSERT INTO `ea_system_menu`
VALUES ('254', '228', 'CURD可视化', 'fa fa fa-shower', 'system.curdGenerate/index', '', '_self', '0', '1', '', '1589623684', '1589623684', null);
-- ----------------------------
-- Table structure for ea_system_node
......@@ -480,6 +482,12 @@ INSERT INTO `ea_system_node`
VALUES ('67', 'system.log', '操作日志管理', '1', '1', '1589623188', '1589623188');
INSERT INTO `ea_system_node`
VALUES ('68', 'system.log/index', '列表', '2', '1', '1589623188', '1589623188');
INSERT INTO `ea_system_node`
VALUES ('69', 'system.curdGenerate', 'CURD可视化管理', '1', '1', '1589623188', '1589623188');
INSERT INTO `ea_system_node`
VALUES ('70', 'system.curdGenerate/index', '列表', '2', '1', '1589623188', '1589623188');
INSERT INTO `ea_system_node`
VALUES ('71', 'system.curdGenerate/save', '操作', '2', '1', '1589623188', '1589623188');
-- ----------------------------
-- Table structure for ea_system_quick
......
......@@ -316,6 +316,12 @@ table样式
line-height: 1em;
}
.layui-form-select dl {
border: 1px #16b777 solid;
border-top: none;
z-index: 99999;
}
.form-search .layui-form-select dl {
top: 31px;
padding: 0;
......
define(["jquery", "easy-admin", "miniTab"], function ($, ea, miniTab) {
var form = layui.form;
var table = layui.table;
var init = {
save_url: 'system.curd_generate/save',
};
var Controller = {
index: function () {
miniTab.listen();
let createStatus = false
let tb_prefix
let tb_name
form.on('submit(search)', function (data) {
let field = data.field
tb_prefix = field.tb_prefix
tb_name = field.tb_name
ea.request.get({url: $(this).attr('lay-submit'), prefix: true, data: field}, function (res) {
createStatus = true
$('.tableShow').removeClass('layui-hide')
$('.table-text').text(field.tb_prefix + field.tb_name)
let _data = res.data
table.render({
elem: '#currentTable', cols: [
[
{field: 'name', title: '字段', minWidth: 80},
{field: 'type', title: '类型', minWidth: 80},
{field: 'key', title: '', minWidth: 80},
{field: 'extra', title: '是否自增', minWidth: 80},
{field: 'null', title: '是否为空', minWidth: 80},
{field: 'desc', title: '描述', minWidth: 80},
]
], data: _data.data, page: false,
});
}, function (error) {
createStatus = false
ea.msg.error(error.msg)
$('.tableShow').addClass('layui-hide')
return
})
form.on('submit(add)', function (data) {
let table = $('.table-text').text()
if (!table || !createStatus) {
ea.msg.error('请先查询数据')
return
}
let url = $(this).attr('lay-submit')
let options = {url: url, prefix: true, data: {tb_prefix: tb_prefix, tb_name: tb_name}}
layer.confirm('确定要自动生成【' + table + '】对应的CURD?', function (index) {
ea.request.post(options, function (res) {
createStatus = true
ea.msg.success(res.msg)
appendHtml(res['data']['result'], res['data']['link'])
}, function (error) {
createStatus = false
let code = error.code
if (code != '1') {
if (code < 0) {
createStatus = true
layer.confirm(error.msg, {
btn: ['确定强制覆盖生成', '取消'], title: '提示', icon: 0,
yes: function () {
options.prefix = false
options.data.force = 1
ea.request.post(options, function (rs) {
createStatus = true
ea.msg.success(rs.msg)
appendHtml(rs['data']['result'], rs['data']['link'])
})
}
});
return
}
ea.msg.error(error.msg)
return
}
})
})
})
form.on('submit(delete)', function (data) {
let table = $('.table-text').text()
if (!table || !createStatus) {
ea.msg.error('请先查询数据')
return
}
let url = $(this).attr('lay-submit')
let options = {url: url, prefix: true, data: {tb_prefix: tb_prefix, tb_name: tb_name}}
layer.confirm('确定要删除【' + table + '】对应CURD的文件?<br>确定清楚自己在做什么!', function (index) {
ea.request.post(options, function (res) {
ea.msg.success(res.msg)
$('.table-text').text('')
$('.file-list').empty()
createStatus = false
})
})
})
return
})
function appendHtml(array, link) {
$('.file-list').empty()
let html = ''
$.each(array, function (idx, item) {
html += '<li class="layui-form-item">' + item + '</li>'
})
html += '<a layuimini-content-href="' + link + '" data-title="页面预览">' +
'<button class="layui-btn"><i class="layui-icon layui-icon-link"></i> 自动生成页面预览</button>' +
'</a>'
$('.file-list').html(html)
}
}
};
return Controller;
});
......@@ -1474,24 +1474,29 @@ define(["jquery", "tableSelect", "ckeditor"], function ($, tableSelect, undefine
if (editorList.length > 0) {
$.each(editorList, function (i, v) {
if (window.CONFIG.EDITOR_TYPE == 'ueditor') {
var name = $(this).attr("name");
try {
UE.getEditor(name, {
initialFrameWidth: '100%',
initialFrameHeight: 420,
initialContent: $(this).data('content'),
toolbars: [
["fullscreen", "source", "|", "undo", "redo", "|", "bold", "italic", "underline", "fontborder", "strikethrough", "superscript", "subscript", "removeformat", "formatmatch", "autotypeset", "blockquote", "pasteplain", "|", "forecolor", "backcolor", "insertorderedlist", "insertunorderedlist", "selectall", "cleardoc", "|", "rowspacingtop", "rowspacingbottom", "lineheight", "|", "customstyle", "paragraph", "fontfamily", "fontsize", "|", "directionalityltr", "directionalityrtl", "indent", "|", "justifyleft", "justifycenter", "justifyright", "justifyjustify", "|", "touppercase", "tolowercase", "|", "link", "unlink", "anchor", "|", "imagenone", "imageleft", "imageright", "imagecenter", "|", "insertimage", "emotion", "insertframe", "insertcode", "pagebreak", "template", "background", "formula", "|", "horizontal", "date", "time", "spechars", "wordimage", "|", "inserttable", "deletetable", "insertparagraphbeforetable", "insertrow", "deleterow", "insertcol", "deletecol", "mergecells", "mergeright", "mergedown", "splittocells", "splittorows", "splittocols", "|", "print", "preview", "searchreplace", "help",]
],
});
} catch (e) {
location.reload()
let name = $(this).attr("name");
let content = $(this).data('content')
let editorOption = {
initialFrameWidth: '100%',
initialFrameHeight: 420,
initialContent: content,
toolbars: [["fullscreen", "source", "|", "undo", "redo", "|", "bold", "italic", "underline", "fontborder", "strikethrough",
"superscript", "subscript", "removeformat", "formatmatch", "autotypeset", "blockquote", "pasteplain", "|",
"forecolor", "backcolor", "insertorderedlist", "insertunorderedlist", "selectall", "cleardoc", "|",
"rowspacingtop", "rowspacingbottom", "lineheight", "|", "customstyle", "paragraph", "fontfamily", "fontsize", "|",
"directionalityltr", "directionalityrtl", "indent", "|", "justifyleft", "justifycenter", "justifyright", "justifyjustify", "|",
"touppercase", "tolowercase", "|", "link", "unlink", "anchor", "|", "imagenone", "imageleft", "imageright", "imagecenter", "|",
"insertimage", "emotion", "insertframe", "insertcode", "pagebreak", "template", "background", "formula", "|",
"horizontal", "date", "time", "spechars", "wordimage", "|",
"inserttable", "deletetable", "insertparagraphbeforetable", "insertrow", "deleterow", "insertcol", "deletecol", "mergecells", "mergeright", "mergedown", "splittocells", "splittorows", "splittocols", "|",
"print", "preview", "searchreplace", "help",
]],
}
setTimeout(function () {
let _UEditor = new baidu.editor.ui.Editor(editorOption);
_UEditor.render(name);
}, 100)
} else {
CKEDITOR.config.fileTools_requestHeaders = {
'X-Requested-With': 'XMLHttpRequest',
'X-Csrf-Token': init.csrf_token,
};
CKEDITOR.replace($(this).attr("name"), {
height: $(this).height(),
filebrowserImageUploadUrl: admin.url('ajax/upload?type=editor'),
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -62,11 +62,7 @@
<div class="layui-form-item">
<label class="layui-form-label">商品描述</label>
<div class="layui-input-block">
@if(sysconfig('site','editor_type')=='ckeditor')
<textarea name="describe" rows="20" class="layui-textarea editor" placeholder="请输入商品描述"></textarea>
@else
<script type="text/plain" id="describe" name="describe" class="editor" data-content=""></script>
@endif
{!!editor_textarea('','describe') !!}
</div>
</div>
......
......@@ -63,11 +63,7 @@
<div class="layui-form-item">
<label class="layui-form-label">商品描述</label>
<div class="layui-input-block">
@if(sysconfig('site','editor_type')=='ckeditor')
<textarea name="describe" rows="20" class="layui-textarea editor" placeholder="请输入商品描述">{{html_entity_decode($row['describe'])}}</textarea>
@else
<script type="text/plain" id="describe" name="describe" class="editor" data-content="{{html_entity_decode($row['describe'])}}"></script>
@endif
{!!editor_textarea($row["describe"],'describe') !!}
</div>
</div>
......
@include('admin.layout.head')
<div class="layuimini-container">
<div class="layuimini-main" id="app">
<div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
<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>
</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-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>
@include('admin.layout.foot')
......@@ -46,7 +46,7 @@
<label class="layui-form-label required">target属性</label>
<div class="layui-input-block">
@foreach(['_self','_blank','_parent','_top'] as $vo)
<input type="radio" name="target" value="{{$vo}}" title="{{$vo}}">
<input type="radio" name="target" value="{{$vo}}" title="{{$vo}}" @if($vo=='_self') checked @endif>
@endforeach
</div>
</div>
......
......@@ -89,7 +89,7 @@
<div class="layui-form-item">
<label class="layui-form-label">管理员密码</label>
<div class="layui-input-block">
<input type="password" class="layui-input" name="password" autocomplete="off" lay-verify="required" lay-reqtext="请输入管理员密码" placeholder="请输入管理员密码">
<input type="password" class="layui-input" name="password" maxlength="20" autocomplete="off" lay-verify="required" lay-reqtext="请输入管理员密码" placeholder="请输入管理员密码">
</div>
</div>
</div>
......