CURD生成器:增强字段类型设置和模板调整

本次更新增强了CURD生成器的字段类型自定义功能,允许开发者通过Web界面设置特定字段的类型,例如忽略字段、下拉字段、单选字段、多选字段、图片字段、多选图片字段、日期字段、日期时间字段和编辑器字段。这些设置会直接影响生成的控制器、模型和视图文件,从而提供更高的灵活性和定制化能力。此外,还对代码模板进行了调整,引入了`$notes`变量来存储字段定义,简化了视图中的脚本处理,并优化了控制器和模型中的代码结构。这些改动旨在改善代码的可读性和可维护性,同时使CURD生成器的使用更加直观和便捷。

通过这次更新,我们希望进一步提升CURD生成器的实用性和用户体验,减少开发者在日常 CRUD操作中重复编写代码的工作量。相关的代码改动包括对`BuildCurd.php`文件的多处调整,以实现新的字段类型设置功能;对`CommonTool.php`的修改,以支持新的数组字符串处理逻辑;对`controller.code`、`curd_generate.js`、`curd_generate.php`、`index.code`和`index.html`等文件的修改,以确保生成的代码与新的设置逻辑兼容,并改善前端交互体验。
This commit is contained in:
wolfcode
2024-07-31 14:47:24 +08:00
parent c5a091c732
commit 7f3a3a85f3
9 changed files with 287 additions and 92 deletions

View File

@@ -59,10 +59,49 @@ class CurdGenerate extends AdminController
}
break;
case "add":
$force = $request->post('force/d', 0);
$tb_fields = $request->param('tb_fields');
$force = $request->post('force/d', 0);
try {
$build = (new BuildCurd())->setTablePrefix($tb_prefix)->setTable($tb_name);
$build->setForce($force); // 强制覆盖
// 新增字段类型
if ($tb_fields) {
foreach ($tb_fields as $tk => $tf) {
if (empty($tf)) continue;
$tf = array_values($tf);
switch ($tk) {
case 'ignore':
$build->setIgnoreFields($tf, true);
break;
case 'select':
$build->setSelectFields($tf, true);
break;
case 'radio':
$build->setRadioFieldSuffix($tf, true);
break;
case 'checkbox':
$build->setCheckboxFieldSuffix($tf, true);
break;
case 'image':
$build->setImageFieldSuffix($tf, true);
break;
case 'images':
$build->setImagesFieldSuffix($tf, true);
break;
case 'date':
$build->setDateFieldSuffix($tf, true);
break;
case 'datetime':
$build->setDatetimeFieldSuffix($tf, true);
break;
case 'editor':
$build->setEditorFields($tf, true);
break;
default:
break;
}
}
}
$build = $build->render();
$fileList = $build->getFileList();
if (empty($fileList)) $this->error('这里什么都没有');

View File

@@ -180,10 +180,15 @@ class BuildCurd
protected array $filesFieldSuffix = ['files'];
/**
* 时间字段后缀
* 日期字段后缀
* @var array
*/
protected array $dateFieldSuffix = ['date', 'time'];
/**
* 日期时间字段后缀
* @var array
*/
protected array $datetimeFieldSuffix = ['datetime'];
/**
* 开关组件字段
@@ -459,9 +464,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setCheckboxFieldSuffix($array): static
public function setCheckboxFieldSuffix($array, $replace = false): static
{
$this->checkboxFieldSuffix = array_merge($this->checkboxFieldSuffix, $array);
$this->checkboxFieldSuffix = $replace ? $array : array_merge($this->checkboxFieldSuffix, $array);
return $this;
}
@@ -470,9 +475,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setRadioFieldSuffix($array): static
public function setRadioFieldSuffix($array, $replace = false): static
{
$this->radioFieldSuffix = array_merge($this->radioFieldSuffix, $array);
$this->radioFieldSuffix = $replace ? $array : array_merge($this->radioFieldSuffix, $array);
return $this;
}
@@ -481,9 +486,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setImageFieldSuffix($array): static
public function setImageFieldSuffix($array, $replace = false): static
{
$this->imageFieldSuffix = array_merge($this->imageFieldSuffix, $array);
$this->imageFieldSuffix = $replace ? $array : array_merge($this->imageFieldSuffix, $array);
return $this;
}
@@ -492,9 +497,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setImagesFieldSuffix($array): static
public function setImagesFieldSuffix($array, $replace = false): static
{
$this->imagesFieldSuffix = array_merge($this->imagesFieldSuffix, $array);
$this->imagesFieldSuffix = $replace ? $array : array_merge($this->imagesFieldSuffix, $array);
return $this;
}
@@ -503,9 +508,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setFileFieldSuffix($array): static
public function setFileFieldSuffix($array, $replace = false): static
{
$this->fileFieldSuffix = array_merge($this->fileFieldSuffix, $array);
$this->fileFieldSuffix = $replace ? $array : array_merge($this->fileFieldSuffix, $array);
return $this;
}
@@ -514,20 +519,31 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setFilesFieldSuffix($array): static
public function setFilesFieldSuffix($array, $replace = false): static
{
$this->filesFieldSuffix = array_merge($this->filesFieldSuffix, $array);
$this->filesFieldSuffix = $replace ? $array : array_merge($this->filesFieldSuffix, $array);
return $this;
}
/**
* 设置时间字段后缀
* 设置日期字段后缀
* @param $array
* @return $this
*/
public function setDateFieldSuffix($array): static
public function setDateFieldSuffix($array, $replace = false): static
{
$this->dateFieldSuffix = array_merge($this->dateFieldSuffix, $array);
$this->dateFieldSuffix = $replace ? $array : array_merge($this->dateFieldSuffix, $array);
return $this;
}
/**
* 设置日期时间字段后缀
* @param $array
* @return $this
*/
public function setDatetimeFieldSuffix($array, $replace = false): static
{
$this->datetimeFieldSuffix = $replace ? $array : array_merge($this->datetimeFieldSuffix, $array);
return $this;
}
@@ -536,9 +552,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setSwitchFields($array): static
public function setSwitchFields($array, $replace = false): static
{
$this->switchFields = array_merge($this->switchFields, $array);
$this->switchFields = $replace ? $array : array_merge($this->switchFields, $array);
return $this;
}
@@ -547,9 +563,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setSelectFields($array): static
public function setSelectFields($array, $replace = false): static
{
$this->selectFields = array_merge($this->selectFields, $array);
$this->selectFields = $replace ? $array : array_merge($this->selectFields, $array);
return $this;
}
@@ -558,9 +574,9 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setSortFields($array): static
public function setSortFields($array, $replace = false): static
{
$this->sortFields = array_merge($this->sortFields, $array);
$this->sortFields = $replace ? $array : array_merge($this->sortFields, $array);
return $this;
}
@@ -569,9 +585,15 @@ class BuildCurd
* @param $array
* @return $this
*/
public function setIgnoreFields($array): static
public function setIgnoreFields($array, $replace = false): static
{
$this->ignoreFields = array_merge($this->ignoreFields, $array);
$this->ignoreFields = $replace ? $array : array_merge($this->ignoreFields, $array);
return $this;
}
public function setEditorFields($array, $replace = false): static
{
$this->editorFields = $replace ? $array : array_merge($this->editorFields, $array);
return $this;
}
@@ -655,6 +677,8 @@ class BuildCurd
$string = $colum['comment'];
$colum['define'] = json_encode([1 => '系统自动生成A', 2 => '请自行修改B'], JSON_UNESCAPED_UNICODE);
// 处理定义类型
preg_match('/{[\s\S]*?}/i', $string, $formTypeMatch);
if (!empty($formTypeMatch) && isset($formTypeMatch[0])) {
@@ -740,7 +764,7 @@ class BuildCurd
* @param $filed
* @return mixed
*/
protected function buildRelationSelectModel($relation, $filed): mixed
protected function buildRelationSelectModel($relation, $field): mixed
{
$relationArray = explode('\\', $relation);
$name = end($relationArray);
@@ -748,9 +772,9 @@ class BuildCurd
$selectCode = CommonTool::replaceTemplate(
$this->getTemplate("model{$this->DS}relationSelect"),
[
'name' => $name,
'name' => "notes['$field']",
'relation' => $relation,
'values' => $filed,
'values' => $field,
]);
return $selectCode;
}
@@ -763,12 +787,12 @@ class BuildCurd
*/
protected function buildOptionView($field, string $select = '')
{
$field = CommonTool::lineToHump(ucfirst($field));
$name = "get{$field}List";
// $field = CommonTool::lineToHump(ucfirst($field));
// $name = "get{$field}List";
return CommonTool::replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}option"),
[
'name' => $name,
'name' => "notes['$field']",
'select' => $select,
]);
}
@@ -781,13 +805,13 @@ class BuildCurd
*/
protected function buildRadioView($field, string $select = ''): mixed
{
$formatField = CommonTool::lineToHump(ucfirst($field));
$name = "get{$formatField}List";
// $formatField = CommonTool::lineToHump(ucfirst($field));
// $name = "get{$formatField}List";
return CommonTool::replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}radioInput"),
[
'field' => $field,
'name' => $name,
'name' => "notes['$field']",
'select' => $select,
]);
}
@@ -800,13 +824,13 @@ class BuildCurd
*/
protected function buildCheckboxView($field, string $select = ''): mixed
{
$formatField = CommonTool::lineToHump(ucfirst($field));
$name = "get{$formatField}List";
// $formatField = CommonTool::lineToHump(ucfirst($field));
// $name = "get{$formatField}List";
return CommonTool::replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}checkboxInput"),
[
'field' => $field,
'name' => $name,
'name' => "notes['$field']",
'select' => $select,
]);
}
@@ -846,16 +870,14 @@ class BuildCurd
// 主表
foreach ($this->tableColumns as $field => $val) {
// 过滤字段
if (in_array($field, $this->ignoreFields)) {
unset($this->tableColumns[$field]);
continue;
}
// 判断是否已初始化
if (isset($this->tableColumns[$field]['formType'])) {
continue;
}
$this->tableColumns[$field]['formType'] = $this->tableColumns[$field]['formType'] ?? 'text';
// 判断图片
if ($this->checkContain($field, $this->imageFieldSuffix)) {
@@ -877,18 +899,35 @@ class BuildCurd
continue;
}
// 判断时间
// 判断日期
if ($this->checkContain($field, $this->dateFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'date';
continue;
}
// 判断日期时间
if ($this->checkContain($field, $this->datetimeFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'datetime';
continue;
}
if (in_array($field, $this->radioFields) || $this->checkContain($field, $this->radioFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'radio';
continue;
}
if (in_array($field, $this->checkboxFields) || $this->checkContain($field, $this->checkboxFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'checkbox';
continue;
}
// 判断开关
if (in_array($field, $this->switchFields)) {
$this->tableColumns[$field]['formType'] = 'switch';
continue;
}
// 判断富文本
if (in_array($field, $this->editorFields) || in_array($val['type'], ['text', 'tinytext', 'mediumtext', 'longtext'])) {
$this->tableColumns[$field]['formType'] = 'editor';
@@ -907,7 +946,6 @@ class BuildCurd
continue;
}
$this->tableColumns[$field]['formType'] = 'text';
}
// 关联表
@@ -1005,17 +1043,17 @@ class BuildCurd
]);
}
$selectList = '';
foreach ($this->relationArray as $relation) {
if (!empty($relation['bindSelectField'])) {
$relationArray = explode('\\', $relation['modelFilename']);
$selectList .= $this->buildSelectController(end($relationArray));
}
}
foreach ($this->tableColumns as $field => $val) {
if (isset($val['formType']) && in_array($val['formType'], ['select', 'switch', 'radio', 'checkbox']) && isset($val['define'])) {
$selectList .= $this->buildSelectController($field);
}
}
// foreach ($this->relationArray as $relation) {
// if (!empty($relation['bindSelectField'])) {
// $relationArray = explode('\\', $relation['modelFilename']);
// $selectList .= $this->buildSelectController(end($relationArray));
// }
// }
// foreach ($this->tableColumns as $field => $val) {
// if (isset($val['formType']) && in_array($val['formType'], ['select', 'switch', 'radio', 'checkbox']) && isset($val['define'])) {
// $selectList .= $this->buildSelectController($field);
// }
// }
$modelFilenameExtend = str_replace($this->DS, '\\', $this->modelFilename);
@@ -1063,19 +1101,19 @@ class BuildCurd
$selectList .= $this->buildRelationSelectModel($relation['modelFilename'], $relation['bindSelectField']);
}
}
$selectArrays = [];
foreach ($this->tableColumns as $field => $val) {
if (isset($val['formType']) && in_array($val['formType'], ['select', 'switch', 'radio', 'checkbox']) && isset($val['define'])) {
$selectList .= $this->buildSelectModel($field, $val['define']);
$selectArrays += [$field => is_array($val['define']) ? $val['define'] : json_decode($val['define'], true)];
}
}
$extendNamespaceArray = explode($this->DS, $this->modelFilename);
$extendNamespace = null;
if (count($extendNamespaceArray) > 1) {
array_pop($extendNamespaceArray);
$extendNamespace = '\\' . implode('\\', $extendNamespaceArray);
}
$modelValue = CommonTool::replaceTemplate(
$modelValue = CommonTool::replaceTemplate(
$this->getTemplate("model{$this->DS}model"),
[
'modelName' => $this->modelName,
@@ -1084,7 +1122,8 @@ class BuildCurd
'table' => $this->table,
'deleteTime' => $this->delete ? '"delete_time"' : 'false',
'relationList' => $relationList,
'selectList' => $selectList,
// 'selectList' => $selectList,
'selectArrays' => CommonTool::replaceArrayString(var_export($selectArrays, true)),
]);
$this->fileList[$modelFile] = $modelValue;
@@ -1135,6 +1174,7 @@ class BuildCurd
$this->getTemplate("view{$this->DS}index"),
[
'controllerUrl' => $this->controllerUrl,
'notesScript' => $this->formatNotesScript(),
]);
$this->fileList[$viewIndexFile] = $viewIndexValue;
@@ -1166,14 +1206,10 @@ class BuildCurd
$val['default'] = '""';
}elseif ($val['formType'] == 'date') {
$templateFile = "view{$this->DS}module{$this->DS}date";
if (!empty($val['define'])) {
$define = $val['define'];
}else {
$define = 'datetime';
}
if (!in_array($define, ['year', 'month', 'date', 'time', 'datetime'])) {
$define = 'datetime';
}
$define = 'date';
}elseif ($val['formType'] == 'datetime') {
$templateFile = "view{$this->DS}module{$this->DS}date";
$define = 'datetime';
}elseif ($val['formType'] == 'radio') {
$templateFile = "view{$this->DS}module{$this->DS}radio";
if (!empty($val['define'])) {
@@ -1194,7 +1230,6 @@ class BuildCurd
}elseif ($field == 'remark' || $val['formType'] == 'textarea') {
$templateFile = "view{$this->DS}module{$this->DS}textarea";
}
$addFormList .= CommonTool::replaceTemplate(
$this->getTemplate($templateFile),
[
@@ -1241,14 +1276,10 @@ class BuildCurd
$value = '$row["' . $field . '"]';
}elseif ($val['formType'] == 'date') {
$templateFile = "view{$this->DS}module{$this->DS}date";
if (!empty($val['define'])) {
$define = $val['define'];
}else {
$define = 'datetime';
}
if (!in_array($define, ['year', 'month', 'date', 'time', 'datetime'])) {
$define = 'datetime';
}
$define = 'date';
}elseif ($val['formType'] == 'datetime') {
$templateFile = "view{$this->DS}module{$this->DS}date";
$define = 'datetime';
}elseif ($val['formType'] == 'radio') {
$templateFile = "view{$this->DS}module{$this->DS}radio";
if (!empty($val['define'])) {
@@ -1316,15 +1347,13 @@ class BuildCurd
continue;
}elseif (in_array($field, $this->switchFields)) {
if (!empty($val['define'])) {
$values = json_encode($val['define'], JSON_UNESCAPED_UNICODE);
$templateValue = "{field: '{$field}', search: 'select', selectList: {$values}, title: '{$val['comment']}', templet: ea.table.switch}";
$templateValue = "{field: '{$field}', search: 'select', selectList: {$field}List, 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'])) {
$values = json_encode($val['define'], JSON_UNESCAPED_UNICODE);
$templateValue = "{field: '{$field}', search: 'select', selectList: {$values}, title: '{$val['comment']}'}";
$templateValue = "{field: '{$field}', search: 'select', selectList: {$field}List, title: '{$val['comment']}'}";
}else {
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
}
@@ -1450,6 +1479,9 @@ class BuildCurd
if (str_starts_with($vo, $string)) {
return true;
}
if (str_ends_with($vo, $string)) {
return true;
}
}
return false;
}
@@ -1493,4 +1525,15 @@ class BuildCurd
return '';
}
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);
}
}

View File

@@ -13,11 +13,14 @@ use think\App;
class {{controllerName}} extends AdminController
{
private array $notes;
public function __construct(App $app)
{
parent::__construct($app);
$this->model = new {{modelFilename}}();
{{selectList}}
$this->notes = $notes = $this->model->notes;
$this->assign(compact('notes'));
}
{{indexMethod}}

View File

@@ -13,7 +13,6 @@ class {{modelName}} extends TimeModel
protected $deleteTime = {{deleteTime}};
{{relationList}}
{{selectList}}
public array $notes = {{selectArrays}};
}

View File

@@ -7,4 +7,8 @@
lay-filter="currentTable">
</table>
</div>
</div>
</div>
<script>
{{notesScript}}
</script>

View File

@@ -14,7 +14,7 @@ class CommonTool
{
$str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) {
return strtoupper($matches[2]);
}, $str);
}, $str);
return $str;
}
@@ -27,7 +27,7 @@ class CommonTool
{
$str = preg_replace_callback('/([A-Z]{1})/', function ($matches) {
return '_' . strtolower($matches[0]);
}, $str);
}, $str);
return $str;
}
@@ -45,11 +45,11 @@ class CommonTool
break;
}
}
} elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
}elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) {
$ip = $_SERVER['HTTP_CLIENT_IP'];
} elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) {
}elseif (isset($_SERVER['HTTP_CF_CONNECTING_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CF_CONNECTING_IP'])) {
$ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
} elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_IP'])) {
}elseif (isset($_SERVER['HTTP_X_REAL_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_X_REAL_IP'])) {
$ip = $_SERVER['HTTP_X_REAL_IP'];
}
return $ip;
@@ -70,7 +70,7 @@ class CommonTool
if (is_dir($path . DIRECTORY_SEPARATOR . $file)) {
$childFiles = self::readDirAllFiles($path . DIRECTORY_SEPARATOR . $file, $basePath);
$list = array_merge($childFiles, $list);
} else {
}else {
$filePath = $path . DIRECTORY_SEPARATOR . $file;
$fileName = str_replace($basePath . DIRECTORY_SEPARATOR, '', $filePath);
$list[$fileName] = $filePath;
@@ -95,4 +95,11 @@ class CommonTool
return $string;
}
public static function replaceArrayString(?string $arrayString): string
{
$arrayString = str_replace('array (', '[', $arrayString);
$arrayString = str_replace(')', ']', $arrayString);
return $arrayString;
}
}

View File

@@ -1,3 +1,9 @@
<style>
.table_fields .input_tag {
margin-bottom: 5px;
display: inline-flex;
}
</style>
<div class="layuimini-container">
<div class="layuimini-main" id="app">
@@ -33,6 +39,62 @@
<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>