tablePrefix = config("database.connections.{$connection}.prefix");
$this->dbName = config("database.connections.{$connection}.database");
$this->dir = __DIR__;
$this->rootDir = root_path();
return $this;
}
public function getTableColumns()
{
return $this->tableColumns;
}
public function setRootDir($dir)
{
$this->rootDir = $dir;
return $this;
}
/**
* 设置主表.
* @param $table
* @return $this
* @throws TableException
*/
public function setTable($table)
{
$this->table = $table;
// 自动检测并处理表前缀
// 支持用户输入带前缀(ul_daka_record)或不带前缀(daka_record)两种方式
// 注意:tablePrefix 可能已包含下划线(如 'ul_'),需要先检测
$this->table = $this->stripTablePrefix($this->table);
$schemeClass = 'app\\admin\\scheme\\' . Str::studly($this->table);
if (!class_exists($schemeClass)) {
throw new TableException("未找到 {$schemeClass},请先执行:php think scheme:make -t {$this->table} 或手动创建 Scheme");
}
try {
$ref = new ReflectionClass($schemeClass);
} catch (\Throwable $e) {
throw new TableException($e->getMessage());
}
$tableAttrs = $ref->getAttributes(Table::class);
if (empty($tableAttrs)) {
throw new TableException("{$schemeClass} 未设置 Table(name: ...) ,无法生成 CURD");
}
/** @var Table $tableAttr */
$tableAttr = $tableAttrs[0]->newInstance();
$expectedTableName = "{$this->tablePrefix}{$this->table}";
if ((string)$tableAttr->name !== $expectedTableName) {
throw new TableException("Scheme 表名不匹配:{$schemeClass} => {$tableAttr->name},期望 {$expectedTableName}");
}
$schemeService = new SchemeToDbService();
try {
$diffs = $schemeService->diff($schemeClass);
} catch (\Throwable $e) {
throw new TableException($e->getMessage());
}
if (!empty($diffs)) {
$message = "CURD 生成已拒绝:数据库结构与 Scheme 不一致({$expectedTableName})\n";
$message .= implode("\n", array_slice($diffs, 0, 50));
$message .= "\n\n请先执行:\n";
$message .= "- 从数据库生成 Scheme:php think scheme:make -t {$this->table}\n";
$message .= "- 或从 Scheme 同步数据库:php think scheme:sync\n\n";
$message .= "详细文档请参考:https://doc.ulthon.com/read/augushong/ulthon_admin/curd-command/zh-cn/2.x.html\n";
throw new TableException($message);
}
$columns = $schemeService->getColumnsForCurd($schemeClass);
foreach ($columns as $field => $colum) {
$this->buildColum($colum);
$this->tableColumns[$field] = $colum;
if ($field == 'delete_time') {
$this->delete = true;
}
}
$this->tableComment = !empty($tableAttr->comment) ? $tableAttr->comment : $this->table;
$this->controllerFilename = $this->getTableControllerName($this->table);
// 初始化默认模型名
$this->modelFilename = Str::studly($this->table);
// 主表模型命名
$modelArray = explode($this->DS, $this->modelFilename);
$this->modelName = array_pop($modelArray);
$this->buildViewJsUrl();
// 构建数据
$this->buildStructure();
return $this;
}
public function getTableControllerName($table)
{
$controllerFilename = '';
// 初始化默认控制器名
$nodeArray = explode('_', $table);
if (count($nodeArray) == 1) {
$controllerFilename = ucfirst($nodeArray[0]);
} else {
foreach ($nodeArray as $k => $v) {
if ($k == 0) {
$controllerFilename = "{$v}{$this->DS}";
} else {
$controllerFilename .= ucfirst($v);
}
}
}
return $controllerFilename;
}
/**
* 去除表前缀.
* @param string $tableName
* @return string
*/
protected function stripTablePrefix($tableName)
{
$prefixToStrip = $this->tablePrefix;
// 如果 tablePrefix 不以 _ 结尾,加上下划线
if (!str_ends_with($prefixToStrip, '_')) {
$prefixToStrip .= '_';
}
if (str_starts_with($tableName, $prefixToStrip)) {
// 用户输入了带前缀的表名,自动去除前缀
return substr($tableName, strlen($prefixToStrip));
}
return $tableName;
}
/**
* 设置关联表.
* @param $relationTable
* @param $foreignKey
* @param null $primaryKey
* @param null $modelFilename
* @param array $onlyShowFileds
* @param null $bindSelectField
* @return $this
* @throws TableException
*/
public function setRelation($relationTable, $foreignKey, $primaryKey = null, $modelFilename = null, $onlyShowFileds = [], $bindSelectField = null)
{
// 自动检测并处理关联表前缀(与 setTable 保持一致)
$relationTable = $this->stripTablePrefix($relationTable);
if (!isset($this->tableColumns[$foreignKey])) {
throw new TableException("主表不存在外键字段:{$foreignKey}");
}
$schemeClass = 'app\\admin\\scheme\\' . Str::studly($relationTable);
if (!class_exists($schemeClass)) {
throw new TableException("未找到 {$schemeClass},请先执行:php think scheme:make -t {$relationTable} 或手动创建 Scheme");
}
try {
$ref = new ReflectionClass($schemeClass);
} catch (\Throwable $e) {
throw new TableException($e->getMessage());
}
$tableAttrs = $ref->getAttributes(Table::class);
if (empty($tableAttrs)) {
throw new TableException("{$schemeClass} 未设置 Table(name: ...) ,无法生成 CURD");
}
/** @var Table $tableAttr */
$tableAttr = $tableAttrs[0]->newInstance();
$expectedTableName = "{$this->tablePrefix}{$relationTable}";
if ((string)$tableAttr->name !== $expectedTableName) {
throw new TableException("关联 Scheme 表名不匹配:{$schemeClass} => {$tableAttr->name},期望 {$expectedTableName}");
}
$schemeService = new SchemeToDbService();
try {
$diffs = $schemeService->diff($schemeClass);
} catch (\Throwable $e) {
throw new TableException($e->getMessage());
}
if (!empty($diffs)) {
$message = "CURD 生成已拒绝:数据库结构与 Scheme 不一致({$expectedTableName})\n";
$message .= implode("\n", array_slice($diffs, 0, 50));
$message .= "\n\n请先执行:\n";
$message .= "- 从数据库生成 Scheme:php think scheme:make -t {$relationTable}\n";
$message .= "- 或从 Scheme 同步数据库:php think scheme:sync\n\n";
$message .= "详细文档请参考:https://doc.ulthon.com/read/augushong/ulthon_admin/curd-command/zh-cn/2.x.html\n";
throw new TableException($message);
}
if (!empty($modelFilename)) {
$modelFilename = str_replace('/', $this->DS, $modelFilename);
}
$allColumns = $schemeService->getColumnsForCurd($schemeClass);
if (!empty($bindSelectField) && !isset($allColumns[$bindSelectField])) {
throw new TableException("关联表{$relationTable}不存在该字段: {$bindSelectField}");
}
if (empty($primaryKey)) {
$primaryKey = $schemeService->getPrimaryKey($schemeClass);
}
if (empty($primaryKey)) {
throw new TableException("关联表{$relationTable}未找到主键字段");
}
$formatColums = $schemeService->getColumnsForCurd($schemeClass, $onlyShowFileds);
$delete = isset($allColumns['delete_time']);
foreach ($formatColums as $field => $colum) {
$this->buildColum($colum);
$formatColums[$field] = $colum;
}
$modelFilename = empty($modelFilename) ? Str::studly($relationTable) : $modelFilename;
$modelArray = explode($this->DS, $modelFilename);
$modelName = array_pop($modelArray);
$relation = [
'modelFilename' => $modelFilename,
'modelName' => $modelName,
'foreignKey' => $foreignKey,
'primaryKey' => $primaryKey,
'bindSelectField' => $bindSelectField,
'delete' => $delete,
'tableColumns' => $formatColums,
];
if (!empty($bindSelectField)) {
$relationArray = explode('\\', $modelFilename);
$this->tableColumns[$foreignKey]['bindSelectField'] = $bindSelectField;
$this->tableColumns[$foreignKey]['bindRelation'] = end($relationArray);
}
$this->relationArray[$relationTable] = $relation;
$this->selectFileds[] = $foreignKey;
return $this;
}
/**
* 设置控制器名.
* @param $controllerFilename
* @return $this
*/
public function setControllerFilename($controllerFilename)
{
$this->controllerFilename = str_replace('/', $this->DS, $controllerFilename);
$this->buildViewJsUrl();
return $this;
}
/**
* 设置模型名.
* @param $modelFilename
* @return $this
*/
public function setModelFilename($modelFilename)
{
$this->modelFilename = str_replace('/', $this->DS, $modelFilename);
$this->buildViewJsUrl();
return $this;
}
/**
* 设置显示字段.
* @param $fields
* @return $this
*/
public function setFields($fields)
{
$this->fields = $fields;
return $this;
}
/**
* 设置删除模式.
* @param $delete
* @return $this
*/
public function setDelete($delete)
{
$this->delete = $delete;
return $this;
}
/**
* 设置是否强制替换.
* @param $force
* @return $this
*/
public function setForce($force)
{
$this->force = $force;
return $this;
}
/**
* 设置复选框字段后缀
* @param $array
* @return $this
*/
public function setCheckboxFieldSuffix($array)
{
$this->checkboxFieldSuffix = array_merge($this->checkboxFieldSuffix, $array);
return $this;
}
/**
* 设置单选框字段后缀
* @param $array
* @return $this
*/
public function setRadioFieldSuffix($array)
{
$this->radioFieldSuffix = array_merge($this->radioFieldSuffix, $array);
return $this;
}
/**
* 设置单图片字段后缀
* @param $array
* @return $this
*/
public function setImageFieldSuffix($array)
{
$this->imageFieldSuffix = array_merge($this->imageFieldSuffix, $array);
return $this;
}
/**
* 设置多图片字段后缀
* @param $array
* @return $this
*/
public function setImagesFieldSuffix($array)
{
$this->imagesFieldSuffix = array_merge($this->imagesFieldSuffix, $array);
return $this;
}
/**
* 设置单文件字段后缀
* @param $array
* @return $this
*/
public function setFileFieldSuffix($array)
{
$this->fileFieldSuffix = array_merge($this->fileFieldSuffix, $array);
return $this;
}
/**
* 设置多文件字段后缀
* @param $array
* @return $this
*/
public function setFilesFieldSuffix($array)
{
$this->filesFieldSuffix = array_merge($this->filesFieldSuffix, $array);
return $this;
}
/**
* 设置时间字段后缀
* @param $array
* @return $this
*/
public function setDateFieldSuffix($array)
{
$this->dateFieldSuffix = array_merge($this->dateFieldSuffix, $array);
return $this;
}
/**
* 设置开关字段.
* @param $array
* @return $this
*/
public function setSwitchFields($array)
{
$this->switchFields = array_merge($this->switchFields, $array);
return $this;
}
/**
* 设置下拉选择字段.
* @param $array
* @return $this
*/
public function setSelectFileds($array)
{
$this->selectFileds = array_merge($this->selectFileds, $array);
return $this;
}
/**
* 设置排序字段.
* @param $array
* @return $this
*/
public function setSortFields($array)
{
$this->sortFields = array_merge($this->sortFields, $array);
return $this;
}
/**
* 设置忽略字段.
* @param $array
* @return $this
*/
public function setIgnoreFields($array)
{
$this->ignoreFields = array_merge($this->ignoreFields, $array);
return $this;
}
/**
* 获取相关的文件.
* @return array
*/
public function getFileList()
{
return $this->fileList;
}
/**
* 构建基础视图、JS、URL.
* @return $this
*/
protected function buildViewJsUrl()
{
$nodeArray = explode($this->DS, $this->controllerFilename);
$formatArray = [];
foreach ($nodeArray as $vo) {
$formatArray[] = Str::snake($vo);
}
$this->controllerUrl = implode('.', $formatArray);
$this->viewFilename = implode($this->DS, $formatArray);
$this->jsFilename = $this->viewFilename;
// 控制器命名空间
$namespaceArray = $nodeArray;
$this->controllerName = array_pop($namespaceArray);
$namespaceSuffix = implode('\\', $namespaceArray);
$this->controllerNamespace = empty($namespaceSuffix) ? "app\admin\controller" : "app\admin\controller\\{$namespaceSuffix}";
return $this;
}
/**
* 构建字段.
* @return $this
*/
protected function buildStructure()
{
foreach ($this->tableColumns as $key => $val) {
// 排序
if (in_array($key, ['sort'])) {
$this->sortFields[] = $key;
}
// 富文本
if (in_array($key, ['describe', 'content', 'details'])) {
$this->editorFields[] = $key;
}
}
return $this;
}
/**
* 构建必填.
* @param $require
* @return string
*/
protected function buildRequiredHtml($require)
{
return $require ? 'lay-verify="required"' : '';
}
/**
* 构建初始化字段信息.
* @param $colum
* @return mixed
*/
protected function buildColum(&$colum)
{
$string = $colum['comment'];
// 处理定义类型
preg_match('/{[\s\S]*?}/i', $string, $formTypeMatch);
if (!empty($formTypeMatch) && isset($formTypeMatch[0])) {
$colum['comment'] = str_replace($formTypeMatch[0], '', $colum['comment']);
$formType = trim(str_replace('}', '', str_replace('{', '', $formTypeMatch[0])));
if (in_array($formType, $this->formTypeArray)) {
$colum['formType'] = $formType;
}
}
// 处理默认定义
preg_match('/\([\s\S]*?\)/i', $string, $defineMatch);
if (!empty($formTypeMatch) && isset($defineMatch[0])) {
$colum['comment'] = str_replace($defineMatch[0], '', $colum['comment']);
if (isset($colum['formType']) && in_array($colum['formType'], ['images', 'files', 'select', 'switch', 'radio', 'checkbox', 'date', 'relation', 'table', 'city'])) {
$define = str_replace(')', '', str_replace('(', '', $defineMatch[0]));
if (in_array($colum['formType'], ['select', 'switch', 'radio', 'checkbox', 'relation', 'table', 'city'])) {
$formatDefine = [];
$explodeArray = explode(',', $define);
foreach ($explodeArray as $vo) {
$voExplodeArray = explode(':', $vo);
if (count($voExplodeArray) == 2) {
$formatDefine[trim($voExplodeArray[0])] = trim($voExplodeArray[1]);
}
}
!empty($formatDefine) && $colum['define'] = $formatDefine;
} else {
$colum['define'] = $define;
}
}
}
$colum['comment'] = trim($colum['comment']);
$colum['property_type'] = $this->fieldTypeToVarType($colum['type']);
$colum['property_name'] = $colum['field'];
$colum['data_list'] = '';
if (isset($colum['formType'])) {
if ($colum['formType'] == 'relation') {
$relation_model_name = '\\app\\admin\\model\\' . Str::studly($colum['define']['table']);
$colum['property_type'] = $relation_model_name;
$colum['property_name'] = Str::camel($colum['define']['table']);
} elseif (in_array($colum['formType'], ['select', 'switch', 'radio', 'checkbox'])) {
$data_list = '';
foreach ($colum['define'] as $define_key => $define_value) {
$data_list .= $define_key . ':' . $define_value . ',';
}
$data_list = substr($data_list, 0, -1);
$colum['data_list'] = $data_list;
}
}
return $colum;
}
/**
* 构建下拉控制器.
* @param $field
* @return mixed
*/
protected function buildSelectController($field)
{
$name = $this->getFieldConstentName($field);
$var_name = $this->getFieldVarName($field);
$selectCode = $this->replaceTemplate(
$this->getTemplate("controller{$this->DS}select"),
[
'name' => $name,
'var_name' => $var_name,
]
);
return $selectCode;
}
/**
* 构架下拉模型.
* @param $field
* @param $array
* @return mixed
*/
protected function buildSelectModel($field, $array)
{
$name = $this->getFieldConstentName($field);
$values = '[';
foreach ($array as $k => $v) {
$values .= "'{$k}' => '{$v}', ";
}
$values = rtrim($values, ', ') . ']';
$selectCode = $this->replaceTemplate(
$this->getTemplate("model{$this->DS}select"),
[
'name' => $name,
'values' => $values,
]
);
return $selectCode;
}
/**
* 构建获取器模型(用于多图片、多文件字段).
* @param $field
* @param $val
* @return mixed
*/
protected function buildAccessorModel($field, $val)
{
// 获取器名称,如 images -> ImagesListAttr
$accessorName = Str::studly($field) . 'List';
$separator = isset($val['define']) ? $val['define'] : '|';
$accessorCode = $this->replaceTemplate(
$this->getTemplate("model{$this->DS}accessor"),
[
'comment' => $val['comment'],
'accessorName' => $accessorName,
'field' => $field,
'separator' => $separator,
]
);
return $accessorCode;
}
/**
* 构建下拉框视图.
* @param $field
* @param string $select
* @return mixed
*/
protected function buildOptionView($field, $select = '')
{
$name = $this->getFieldVarName($field);
$optionCode = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}option"),
[
'name' => $name,
'select' => $select,
]
);
return $optionCode;
}
protected function buildCityView($field, $options, $value)
{
$default_define = [
'comment' => $options['comment'],
'field' => $field,
'required' => $this->buildRequiredHtml($options['required']),
'value' => $value,
'level' => '',
];
$define = array_merge($default_define, $options['define']);
$formatTargetList = [];
$formatTargetList['name'] = 1;
$formatTargetList['code'] = 1;
$formatTargetList['name-province'] = 1;
$formatTargetList['name-city'] = 1;
$formatTargetList['name-district'] = 1;
$formatTargetList['code-province'] = 1;
$formatTargetList['code-city'] = 1;
$formatTargetList['code-district'] = 1;
$submit_field_content = '';
foreach ($formatTargetList as $key => $value) {
if (isset($define[$key])) {
$submit_field_content .= 'data-field-' . $key . '="' . $define[$key] . '" ';
}
}
$define['submit_field_content'] = $submit_field_content;
$city_main_code = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}cityMain"),
$define
);
return $city_main_code;
}
/**
* 构建表格选择器视图.
* @param $field
* @param string $select
* @return mixed
*/
protected function buildTableView($field, $options, $value)
{
$default_define = [
'table' => '',
// 必填
'type' => 'checkbox',
'valueField' => 'id',
'fieldName' => 'title',
// 必填
'comment' => $options['comment'],
'field' => $field,
'required' => $options['required'],
'value' => $value,
];
$define = array_merge($default_define, $options['define']);
$table_controller_name = $this->getTableControllerName($define['table']);
$nodeArray = explode($this->DS, $table_controller_name);
$formatArray = [];
foreach ($nodeArray as $vo) {
$formatArray[] = Str::snake($vo);
}
$controller_url = implode('.', $formatArray);
$define['controller_url'] = $controller_url;
$table_main_code = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}tableMain"),
$define
);
return $table_main_code;
}
/**
* 构建单选框视图.
* @param $field
* @param string $select
* @return mixed
*/
protected function buildRadioView($field, $select = '')
{
$name = $this->getFieldVarName($field);
$optionCode = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}radioInput"),
[
'field' => $field,
'name' => $name,
'select' => $select,
]
);
return $optionCode;
}
/**
* 构建多选框视图.
* @param $field
* @param string $select
* @return mixed
*/
protected function buildCheckboxView($field, $select = '')
{
$name = $this->getFieldVarName($field);
$optionCode = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}module{$this->DS}checkboxInput"),
[
'field' => $field,
'name' => $name,
'select' => $select,
]
);
return $optionCode;
}
/**
* 初始化.
* @return $this
*/
public function render()
{
// 初始化数据
$this->renderData();
// 控制器
$this->renderController();
// 模型
$this->renderModel();
// 视图
$this->renderView();
// JS
$this->renderJs();
return $this;
}
/**
* 初始化数据.
* @return $this
*/
protected function renderData()
{
// 主表
foreach ($this->tableColumns as $field => $val) {
// 过滤字段
if (in_array($field, $this->ignoreFields)) {
unset($this->tableColumns[$field]);
continue;
}
// 判断是否已初始化
if (isset($this->tableColumns[$field]['formType'])) {
continue;
}
// 判断图片
if ($this->checkContain($field, $this->imageFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'image';
continue;
}
if ($this->checkContain($field, $this->imagesFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'images';
continue;
}
// 判断文件
if ($this->checkContain($field, $this->fileFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'file';
continue;
}
if ($this->checkContain($field, $this->filesFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'files';
continue;
}
// 判断时间
if ($this->checkContain($field, $this->dateFieldSuffix)) {
$this->tableColumns[$field]['formType'] = 'date';
continue;
}
// 判断开关
if (in_array($field, $this->switchFields)) {
$this->tableColumns[$field]['formType'] = 'switch';
continue;
}
// 判断富文本
if (in_array($field, $this->editorFields)) {
$this->tableColumns[$field]['formType'] = 'editor';
continue;
}
// 判断排序
if (in_array($field, $this->sortFields)) {
$this->tableColumns[$field]['formType'] = 'sort';
continue;
}
// 判断下拉选择
if (in_array($field, $this->selectFileds)) {
$this->tableColumns[$field]['formType'] = 'select';
continue;
}
$this->tableColumns[$field]['formType'] = 'text';
}
// 关联表
foreach ($this->relationArray as $table => $tableVal) {
foreach ($tableVal['tableColumns'] as $field => $val) {
// 过滤字段
if (in_array($field, $this->ignoreFields)) {
unset($this->relationArray[$table]['tableColumns'][$field]);
continue;
}
// 判断是否已初始化
if (isset($this->relationArray[$table]['tableColumns'][$field]['formType'])) {
continue;
}
// 判断图片
if ($this->checkContain($field, $this->imageFieldSuffix)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'image';
continue;
}
if ($this->checkContain($field, $this->imagesFieldSuffix)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'images';
continue;
}
// 判断文件
if ($this->checkContain($field, $this->fileFieldSuffix)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'file';
continue;
}
if ($this->checkContain($field, $this->filesFieldSuffix)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'files';
continue;
}
// 判断时间
if ($this->checkContain($field, $this->dateFieldSuffix)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'date';
continue;
}
// 判断开关
if (in_array($field, $this->switchFields)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'switch';
continue;
}
// 判断富文本
if (in_array($field, $this->editorFields)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'editor';
continue;
}
// 判断排序
if (in_array($field, $this->sortFields)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'sort';
continue;
}
// 判断下拉选择
if (in_array($field, $this->selectFileds)) {
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'select';
continue;
}
$this->relationArray[$table]['tableColumns'][$field]['formType'] = 'text';
}
}
return $this;
}
/**
* 初始化控制器.
* @return $this
*/
protected function renderController()
{
$controllerFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}controller{$this->DS}{$this->controllerFilename}.php";
$relationSearch = '';
if (empty($this->relationArray)) {
$controllerIndexMethod = '';
$controllerExportMethod = '';
} else {
$relationCode = '';
$relation_table = [];
foreach ($this->relationArray as $key => $val) {
$relation = Str::camel($key);
$relation_table[] = $relation;
}
$relationCode = "->withJoin(['" . implode('\',\'', $relation_table) . "'], 'LEFT')\r";
$controllerIndexMethod = $this->replaceTemplate(
$this->getTemplate("controller{$this->DS}indexMethod"),
[
'relationIndexMethod' => $relationCode,
]
);
$controllerExportMethod = $this->replaceTemplate(
$this->getTemplate("controller{$this->DS}exportMethod"),
[
'relationIndexMethod' => trim($relationCode),
]
);
$relationSearch = $this->replaceTemplate(
$this->getTemplate("controller{$this->DS}relationSearch")
);
}
$selectList = '';
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);
$controllerValue = $this->replaceTemplate(
$this->getTemplate("controller{$this->DS}controller"),
[
'controllerName' => $this->controllerName,
'controllerNamespace' => $this->controllerNamespace,
'controllerAnnotation' => $this->tableComment,
'modelFilename' => "\app\admin\model\\{$modelFilenameExtend}",
'indexMethod' => $controllerIndexMethod,
'exportMethod' => $controllerExportMethod,
'selectList' => $selectList,
'relationSearch' => $relationSearch,
]
);
$this->fileList[$controllerFile] = $controllerValue;
return $this;
}
/**
* 初始化模型.
* @return $this
*/
protected function renderModel()
{
// 主表模型
$modelFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}model{$this->DS}{$this->modelFilename}.php";
if (empty($this->relationArray)) {
$relationList = '';
} else {
$relationList = '';
foreach ($this->relationArray as $key => $val) {
$relation = Str::camel($key);
$relationCode = $this->replaceTemplate(
$this->getTemplate("model{$this->DS}relation"),
[
'relationMethod' => $relation,
'relationModel' => "\app\admin\model\\{$val['modelFilename']}",
'foreignKey' => $val['foreignKey'],
'primaryKey' => $val['primaryKey'],
]
);
$relationList .= $relationCode;
}
}
$selectList = '';
$accessorList = '';
$doc_content = '';
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']);
}
// 为多图片、多文件、多选字段生成获取器
if (in_array($val['formType'], ['images', 'files', 'checkbox'])) {
// checkbox 使用逗号分隔,images/files 使用自定义分隔符
if ($val['formType'] == 'checkbox') {
$val['define'] = ','; // 多选框固定使用逗号分隔
} elseif ($val['formType'] == 'images' || $val['formType'] == 'files') {
if (!isset($val['define'])) {
$val['define'] = '|'; // 默认分隔符
}
}
$accessorList .= $this->buildAccessorModel($field, $val);
}
$doc_content .= " * @property {$val['property_type']} \${$val['property_name']} {$val['comment']} {$val['data_list']}\n";
}
$doc_content = substr($doc_content, 0, -1);
$extendNamespaceArray = explode($this->DS, $this->modelFilename);
$extendNamespace = null;
if (count($extendNamespaceArray) > 1) {
array_pop($extendNamespaceArray);
$extendNamespace = '\\' . implode('\\', $extendNamespaceArray);
}
$modelValue = $this->replaceTemplate(
$this->getTemplate("model{$this->DS}model"),
[
'modelName' => $this->modelName,
'modelNamespace' => "app\admin\model{$extendNamespace}",
'table' => $this->table,
'deleteTime' => $this->delete ? '"delete_time"' : 'false',
'relationList' => $relationList,
'selectList' => $selectList,
'accessorList' => $accessorList,
'doc_content' => $doc_content,
]
);
$this->fileList[$modelFile] = $modelValue;
// 关联模型
foreach ($this->relationArray as $key => $val) {
$relationModelFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}model{$this->DS}{$val['modelFilename']}.php";
// todo 判断关联模型文件是否存在, 存在就不重新生成文件, 防止关联模型文件被覆盖
$relationModelClass = "\\app\\admin\\model\\{$val['modelFilename']}";
if (class_exists($relationModelClass) && method_exists(new $relationModelClass, 'getName')) {
$tableName = (new $relationModelClass)->getName();
if (Str::snake($tableName) == Str::snake($key)) {
continue;
}
}
$extendNamespaceArray = explode($this->DS, $val['modelFilename']);
$extendNamespace = null;
if (count($extendNamespaceArray) > 1) {
array_pop($extendNamespaceArray);
$extendNamespace = '\\' . implode('\\', $extendNamespaceArray);
}
$relationModelValue = $this->replaceTemplate(
$this->getTemplate("model{$this->DS}model"),
[
'modelName' => $val['modelName'],
'modelNamespace' => "app\admin\model{$extendNamespace}",
'table' => $key,
'deleteTime' => $val['delete'] ? '"delete_time"' : 'false',
'relationList' => '',
'selectList' => '',
]
);
$this->fileList[$relationModelFile] = $relationModelValue;
}
return $this;
}
/**
* 初始化视图.
* @return $this
*/
protected function renderView()
{
// 列表页面
$viewIndexFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}index.html";
$viewIndexValue = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}index"),
[
'controllerUrl' => $this->controllerUrl,
]
);
$this->fileList[$viewIndexFile] = $viewIndexValue;
// 添加页面
$viewAddFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}add.html";
$addFormList = '';
foreach ($this->tableColumns as $field => $val) {
if (in_array($field, ['id', 'create_time'])) {
continue;
}
$defaultFromRequestComponent = '{$Request.param.' . $field . '|default=\'' . $val['default'] . '\'}';
$defaultFromRequestVar = '$Request.param.' . $field;
$templateFile = "view{$this->DS}module{$this->DS}input";
$define = '';
// 根据formType去获取具体模板
if ($val['formType'] == 'image') {
$templateFile = "view{$this->DS}module{$this->DS}image";
} elseif ($val['formType'] == 'images') {
$templateFile = "view{$this->DS}module{$this->DS}images";
$define = isset($val['define']) ? $val['define'] : '|';
} elseif ($val['formType'] == 'file') {
$templateFile = "view{$this->DS}module{$this->DS}file";
} elseif ($val['formType'] == 'files') {
$templateFile = "view{$this->DS}module{$this->DS}files";
$define = isset($val['define']) ? $val['define'] : '|';
} elseif ($val['formType'] == 'editor') {
$templateFile = "view{$this->DS}module{$this->DS}editor";
} elseif ($val['formType'] == 'date') {
$templateFile = "view{$this->DS}module{$this->DS}date";
if (isset($val['define']) && !empty($val['define'])) {
$define = $val['define'];
} else {
$define = 'datetime';
}
if (!in_array($define, ['year', 'month', 'date', 'time', 'datetime'])) {
$define = 'datetime';
}
} elseif ($val['formType'] == 'radio' || $val['formType'] == 'switch') {
$templateFile = "view{$this->DS}module{$this->DS}radio";
if (isset($val['define']) && !empty($val['define'])) {
$define = $this->buildRadioView($field, '{in name="k" value="' . $defaultFromRequestVar . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'checkbox') {
$templateFile = "view{$this->DS}module{$this->DS}checkbox";
if (isset($val['define']) && !empty($val['define'])) {
$define = $this->buildCheckboxView($field, '{in name="k" value="' . $defaultFromRequestVar . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'select') {
$templateFile = "view{$this->DS}module{$this->DS}select";
if (isset($val['bindRelation'])) {
// TODO:这里的兼容关联不知道还有没有用,可能是技术债务,需要清理
$define = $this->buildOptionView($val['bindRelation']);
} elseif (isset($val['define']) && !empty($val['define'])) {
$define = $this->buildOptionView($field, '{in name="k" value="' . $defaultFromRequestVar . '"}selected=""{/in}');
}
} elseif (in_array($field, ['remark']) || $val['formType'] == 'textarea') {
$templateFile = "view{$this->DS}module{$this->DS}textarea";
} elseif ($val['formType'] == 'relation') {
$val['define']['type'] = 'radio';
$val['define']['valueField'] = 'id';
$val['define']['fieldName'] = $val['define']['relationBindSelect'];
$templateFile = "view{$this->DS}module{$this->DS}table";
$define = $this->buildTableView($field, $val, $defaultFromRequestComponent);
} elseif ($val['formType'] == 'table') {
$templateFile = "view{$this->DS}module{$this->DS}table";
$define = $this->buildTableView($field, $val, $defaultFromRequestComponent);
} elseif ($val['formType'] == 'city') {
$templateFile = "view{$this->DS}module{$this->DS}city";
$define = $this->buildCityView($field, $val, $defaultFromRequestComponent);
} elseif ($val['formType'] == 'tag') {
$templateFile = "view{$this->DS}module{$this->DS}tag";
}
$addFormList .= $this->replaceTemplate(
$this->getTemplate($templateFile),
[
'comment' => $val['comment'],
'field' => $field,
'required' => $this->buildRequiredHtml($val['required']),
'required_text' => $val['required'] ? '1' : '',
'value' => $defaultFromRequestComponent,
'define' => $define,
]
);
}
$viewAddValue = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}form"),
[
'formList' => $addFormList,
]
);
$this->fileList[$viewAddFile] = $viewAddValue;
// 编辑页面
$viewEditFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}edit.html";
$editFormList = '';
foreach ($this->tableColumns as $field => $val) {
if (in_array($field, ['id', 'create_time'])) {
continue;
}
$templateFile = "view{$this->DS}module{$this->DS}input";
$define = '';
$value = '{$row.' . $field . '|default=\'\'}';
// 根据formType去获取具体模板
if ($val['formType'] == 'image') {
$templateFile = "view{$this->DS}module{$this->DS}image";
} elseif ($val['formType'] == 'images') {
$templateFile = "view{$this->DS}module{$this->DS}images";
} elseif ($val['formType'] == 'file') {
$templateFile = "view{$this->DS}module{$this->DS}file";
} elseif ($val['formType'] == 'files') {
$templateFile = "view{$this->DS}module{$this->DS}files";
} elseif ($val['formType'] == 'editor') {
$templateFile = "view{$this->DS}module{$this->DS}editor";
$value = '{$row.' . $field . '|raw|default=\'\'}';
} elseif ($val['formType'] == 'date') {
$templateFile = "view{$this->DS}module{$this->DS}date";
if (isset($val['define']) && !empty($val['define'])) {
$define = $val['define'];
} else {
$define = 'datetime';
}
if (!in_array($define, ['year', 'month', 'date', 'time', 'datetime'])) {
$define = 'datetime';
}
} elseif ($val['formType'] == 'radio' || $val['formType'] == 'switch') {
$templateFile = "view{$this->DS}module{$this->DS}radio";
if (isset($val['define']) && !empty($val['define'])) {
$define = $this->buildRadioView($field, '{in name="k" value="$row.' . $field . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'checkbox') {
$templateFile = "view{$this->DS}module{$this->DS}checkbox";
if (isset($val['define']) && !empty($val['define'])) {
$define = $this->buildCheckboxView($field, '{in name="k" value="$row.' . $field . '"}checked=""{/in}');
}
} elseif ($val['formType'] == 'select') {
$templateFile = "view{$this->DS}module{$this->DS}select";
if (isset($val['bindRelation'])) {
// TODO:这里的兼容关联不知道还有没有用,可能是技术债务,需要清理
$define = $this->buildOptionView($val['bindRelation'], '{in name="k" value="$row.' . $field . '"}selected=""{/in}');
} elseif (isset($val['define']) && !empty($val['define'])) {
$define = $this->buildOptionView($field, '{in name="k" value="$row.' . $field . '"}selected=""{/in}');
}
} elseif (in_array($field, ['remark']) || $val['formType'] == 'textarea') {
$templateFile = "view{$this->DS}module{$this->DS}textarea";
$value = '{$row.' . $field . '|raw|default=\'\'}';
} elseif ($val['formType'] == 'relation') {
$val['define']['type'] = 'radio';
$val['define']['valueField'] = 'id';
$val['define']['fieldName'] = $val['define']['relationBindSelect'];
$templateFile = "view{$this->DS}module{$this->DS}table";
$define = $this->buildTableView($field, $val, $value);
} elseif ($val['formType'] == 'table') {
$templateFile = "view{$this->DS}module{$this->DS}table";
$define = $this->buildTableView($field, $val, $value);
} elseif ($val['formType'] == 'city') {
$templateFile = "view{$this->DS}module{$this->DS}city";
$define = $this->buildCityView($field, $val, $value);
} elseif ($val['formType'] == 'tag') {
$templateFile = "view{$this->DS}module{$this->DS}tag";
}
$editFormList .= $this->replaceTemplate(
$this->getTemplate($templateFile),
[
'comment' => $val['comment'],
'field' => $field,
'required' => $this->buildRequiredHtml($val['required']),
'required_text' => $val['required'] ? '1' : '',
'value' => $value,
'define' => $define,
]
);
}
$viewEditValue = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}form"),
[
'formList' => $editFormList,
]
);
$this->fileList[$viewEditFile] = $viewEditValue;
// 详情页面
$viewReadFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}read.html";
$mainFields = '';
$basicFields = '';
// 定义基础字段(右侧显示)
$basicFieldList = ['id', 'create_time', 'update_time', 'status', 'sort', 'delete_time'];
foreach ($this->tableColumns as $field => $val) {
if (in_array($field, ['id'])) {
continue;
}
$fieldContent = $this->buildReadFieldContent($field, $val);
// 根据字段类型分配到不同区域
if (in_array($field, $basicFieldList)) {
$basicFields .= $fieldContent;
} else {
$mainFields .= $fieldContent;
}
}
$viewReadValue = $this->replaceTemplate(
$this->getTemplate("view{$this->DS}read"),
[
'mainFields' => $mainFields,
'basicFields' => $basicFields,
]
);
$this->fileList[$viewReadFile] = $viewReadValue;
return $this;
}
/**
* 初始化JS.
* @return $this
*/
protected function renderJs()
{
$index_js_file = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}index.js";
$indexCols = " {type: 'checkbox'},\r";
// 主表字段
foreach ($this->tableColumns as $field => $val) {
$var_name = $this->getFieldVarName($field);
if ($val['formType'] == 'image') {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ua.table.image}";
} elseif ($val['formType'] == 'images') {
continue;
} elseif ($val['formType'] == 'file') {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ua.table.url}";
} elseif ($val['formType'] == 'files') {
continue;
} elseif ($val['formType'] == 'editor') {
continue;
} elseif ($val['formType'] == 'table') {
continue;
} elseif (in_array($field, $this->switchFields)) {
if (isset($val['define']) && !empty($val['define'])) {
$templateValue = "{field: '{$field}', search: 'select', selectList: ua.getDataBrage('{$var_name}'), title: '{$val['comment']}', templet: ua.table.switch}";
} else {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ua.table.switch}";
}
} elseif (in_array($val['formType'], ['select', 'checkbox', 'radio', 'switch'])) {
if (isset($val['define']) && !empty($val['define'])) {
$templateValue = "{field: '{$field}', search: 'select', selectList: ua.getDataBrage('{$var_name}'), title: '{$val['comment']}'}";
} else {
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
}
} elseif (in_array($field, ['remark'])) {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ua.table.text}";
} elseif (in_array($field, $this->sortFields)) {
$templateValue = "{field: '{$field}', title: '{$val['comment']}', edit: 'text'}";
} else {
$templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
}
$indexCols .= $this->formatColsRow("{$templateValue},\r");
}
// 关联表
foreach ($this->relationArray as $table => $tableVal) {
$table = Str::camel($table);
foreach ($tableVal['tableColumns'] as $field => $val) {
if ($val['formType'] == 'image') {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ua.table.image}";
} elseif ($val['formType'] == 'images') {
continue;
} elseif ($val['formType'] == 'file') {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ua.table.url}";
} elseif ($val['formType'] == 'files') {
continue;
} elseif ($val['formType'] == 'editor') {
continue;
} elseif ($val['formType'] == 'table') {
continue;
} elseif ($val['formType'] == 'select') {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
} elseif (in_array($field, ['remark'])) {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ua.table.text}";
} elseif (in_array($field, $this->switchFields)) {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ua.table.switch}";
} elseif (in_array($field, $this->sortFields)) {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', edit: 'text'}";
} else {
$templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
}
$indexCols .= $this->formatColsRow("{$templateValue},\r");
}
}
$indexCols .= $this->formatColsRow("{
width: 250, title: '操作', templet: ua.table.tool, fixed: 'right', operat: [
[{
class: 'layui-btn layui-btn-primary layui-btn-xs',
method: 'tab',
field: 'id',
text: '详情',
title: '查看详情',
auth: 'read',
url: init.readUrl,
icon: ''
}],
'edit',
'delete'
]
},
");
$js_index = $this->replaceTemplate(
$this->getTemplate("js{$this->DS}index"),
[
'indexCols' => $indexCols,
]
);
$this->fileList[$index_js_file] = $js_index;
$js_common_file = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}_common.js";
$js_common = $this->replaceTemplate(
$this->getTemplate("js{$this->DS}_common"),
[
'controllerUrl' => $this->controllerUrl,
]
);
$this->fileList[$js_common_file] = $js_common;
$js_add_file = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}add.js";
$js_edit_file = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}edit.js";
$js_read_file = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}read.js";
$js_add = $this->replaceTemplate($this->getTemplate("js{$this->DS}add"));
$this->fileList[$js_add_file] = $js_add;
$js_edit = $this->replaceTemplate($this->getTemplate("js{$this->DS}edit"));
$this->fileList[$js_edit_file] = $js_edit;
$js_read = $this->replaceTemplate($this->getTemplate("js{$this->DS}read"));
$this->fileList[$js_read_file] = $js_read;
return $this;
}
/**
* 检测文件.
* @return $this
*/
protected function check()
{
// 是否强制性
if ($this->force) {
return $this;
}
foreach ($this->fileList as $key => $val) {
if (is_file($key)) {
throw new FileException("文件已存在:{$key}");
}
}
return $this;
}
/**
* 开始生成.
* @return array
*/
public function create()
{
$this->check();
foreach ($this->fileList as $key => $val) {
// 判断文件夹是否存在,不存在就创建
$fileArray = explode($this->DS, $key);
array_pop($fileArray);
$fileDir = implode($this->DS, $fileArray);
if (!is_dir($fileDir)) {
mkdir($fileDir, 0775, true);
}
// 写入
file_put_contents($key, $val);
}
return array_keys($this->fileList);
}
/**
* 开始删除.
* @return array
*/
public function delete()
{
$deleteFile = [];
foreach ($this->fileList as $key => $val) {
if (is_file($key)) {
unlink($key);
$deleteFile[] = $key;
}
}
return $deleteFile;
}
/**
* 检测字段后缀
* @param $string
* @param $array
* @return bool
*/
protected function checkContain($string, $array)
{
foreach ($array as $vo) {
if (substr($string, 0, strlen($vo)) === $vo) {
return true;
}
}
return false;
}
/**
* 格式化表单行.
* @param $value
* @return string
*/
protected function formatColsRow($value)
{
return " {$value}";
}
/**
* 获取对应的模板信息.
* @param $name
* @return false|string
*/
protected function getTemplate($name)
{
return file_get_contents("{$this->dir}{$this->DS}templates{$this->DS}{$name}.code");
}
public function getFieldConstentName($field)
{
$field = Str::studly($field);
$name = "SelectList{$field}";
$name = Str::snake($name);
$name = Str::upper($name);
return $name;
}
public function getFieldVarName($field)
{
$field = Str::studly($field);
$name = "SelectList{$field}";
$name = Str::snake($name);
return $name;
}
public function getFieldMethodName($field)
{
$field = Str::studly($field);
$name = "getList{$field}";
return $name;
}
/**
* 模板值替换.
* @param $string
* @param $array
* @return mixed
*/
public function replaceTemplate($string, $array = [])
{
foreach ($array as $key => $val) {
$string = str_replace('{{' . $key . '}}', $val ?? '', $string);
}
return $string;
}
public function fieldTypeToVarType($type)
{
$type_prefix_map = [
'BIT' => 'bool',
'TINYINT' => 'int',
'BOOL' => 'bool',
'BOOLEAN' => 'bool',
'SMALLINT' => 'int',
'MEDIUMINT' => 'int',
'INT' => 'int',
'INTEGER' => 'int',
'BIGINT' => 'int',
'FLOAT' => 'float|double',
'DOUBLE' => 'float|double',
'DECIMAL' => 'float|double',
'DATE' => 'string',
'DATETIME' => 'string',
'TIMESTAMP' => 'int',
'TIME' => 'string',
'YEAR' => 'int',
'CHAR' => 'string',
'VARCHAR' => 'string',
'BINARY' => 'string',
'VARBINARY' => 'string',
'TINYBLOB' => 'string',
'BLOB' => 'string',
'MEDIUMBLOB' => 'string',
'LONGBLOB' => 'string',
'TINYTEXT' => 'string',
'TEXT' => 'string',
'MEDIUMTEXT' => 'string',
'LONGTEXT' => 'string',
'ENUM' => 'string',
'SET' => 'string',
'JSON' => 'string',
];
foreach ($type_prefix_map as $sql_type => $var_type) {
if (Str::startsWith(strtolower($type), strtolower($sql_type))) {
return $var_type;
}
}
return 'mixed';
}
/**
* 构建详情页字段内容
* @param $field
* @param $val
* @return string
*/
protected function buildReadFieldContent($field, $val)
{
$templateFile = "view{$this->DS}module{$this->DS}readText";
$define = '';
// 根据formType去获取具体的详情页模板
if ($val['formType'] == 'image') {
$templateFile = "view{$this->DS}module{$this->DS}readImage";
} elseif ($val['formType'] == 'images') {
$templateFile = "view{$this->DS}module{$this->DS}readImages";
$define = isset($val['define']) ? $val['define'] : '|';
} elseif ($val['formType'] == 'file') {
$templateFile = "view{$this->DS}module{$this->DS}readFile";
} elseif ($val['formType'] == 'files') {
$templateFile = "view{$this->DS}module{$this->DS}readFiles";
$define = isset($val['define']) ? $val['define'] : '|';
} elseif ($val['formType'] == 'editor') {
$templateFile = "view{$this->DS}module{$this->DS}readEditor";
} elseif (in_array($field, ['remark']) || $val['formType'] == 'textarea') {
$templateFile = "view{$this->DS}module{$this->DS}readTextarea";
} elseif ($val['formType'] == 'date') {
$templateFile = "view{$this->DS}module{$this->DS}readDate";
} elseif ($val['formType'] == 'radio' || $val['formType'] == 'switch') {
$templateFile = "view{$this->DS}module{$this->DS}readSwitch";
if (isset($val['define']) && !empty($val['define'])) {
// 使用 kv 格式直接获取值
$var_name = $this->getFieldVarName($field);
$define = '{$' . $var_name . '[$row.' . $field . ']|default=\'\'}';
}
} elseif ($val['formType'] == 'checkbox') {
$templateFile = "view{$this->DS}module{$this->DS}readSelect";
if (isset($val['define']) && !empty($val['define'])) {
$var_name = $this->getFieldVarName($field);
// 使用获取器列表,如 shop_type_list
$define = '{volist name="row.' . $field . '_list" id="item"}{$' . $var_name . '[$item]|default=\'\'}{/volist}';
}
} elseif ($val['formType'] == 'select') {
$templateFile = "view{$this->DS}module{$this->DS}readSelect";
if (isset($val['bindRelation'])) {
$define = '{$row.' . $field . '}';
} elseif (isset($val['define']) && !empty($val['define'])) {
$var_name = $this->getFieldVarName($field);
$define = '{$' . $var_name . '[$row.' . $field . ']|default=\'\'}';
}
} elseif ($val['formType'] == 'relation') {
// 关联表字段暂时使用文本显示
$templateFile = "view{$this->DS}module{$this->DS}readText";
} elseif ($val['formType'] == 'table') {
// 表格选择器暂时使用文本显示
$templateFile = "view{$this->DS}module{$this->DS}readText";
} elseif ($val['formType'] == 'city') {
// 城市选择器暂时使用文本显示
$templateFile = "view{$this->DS}module{$this->DS}readText";
} elseif ($val['formType'] == 'tag') {
// 标签暂时使用文本显示
$templateFile = "view{$this->DS}module{$this->DS}readText";
}
$fieldContent = $this->replaceTemplate(
$this->getTemplate($templateFile),
[
'comment' => $val['comment'],
'field' => $field,
'define' => $define,
]
);
return $fieldContent;
}
}