tableId = $tableId; $this->needCreateTable = $needCreateTable; } public function execute() { $table = Table::find($this->tableId); if (!$table) { $this->setError('table_id参数错误'); return false; } if($table->table == 'lt_admin_user'){ $this->setError('lt_admin_user表暂不支持生成'); return false; } //这里来删除lt_migrations表对当前表的记录 $this->database = $table->database; $this->tableName = $table->table; $this->tableComment = $table->comment; $this->engine = $table->engine; $this->collation = $table->collation; $this->isHidePk = $table->is_hide_pk; $this->isCreateNumber = $table->is_create_number; $this->fields = Field::where('table_id', '=', $this->tableId)->order(['show_sort' => 'desc', 'id' => 'asc'])->select(); if (!$this->fields) { $this->setError($this->tableName . '还没有字段,请先添加字段'); return false; } $this->hasSoftDel = false; //是否拥有软删除功能 foreach ($this->fields as $k => $v) { if ($v->field == 'delete_time') { $this->hasSoftDel = true; } } $this->setParam(); if(!$this->createMigration()){ return false; } $this->create(); return true; } /** * 设置参数,待生成 */ public function setParam() { $this->setMidFileName(); $this->setMigrationFileName(); $this->setFileName(); $this->setMigrationParam(); $this->setControllerParam(); $this->setModelParam(); $this->setJsParam(); $this->setHtmlParam(); $this->setValidateParam(); } /** * 生成静态文件、控制器和模型文件 */ public function create() { // $this->createMigration(); $this->createController(); $this->createModel(); $this->createJs(); $this->createHtml(); $this->createValidate(); } /** * 设置当前生成的类路径名称 */ protected function setMidFileName() { $arrTable = explode('_', $this->tableName); $basename = ucfirst($arrTable[count($arrTable) - 1]); $this->controllerModelClassName = $basename; array_shift($arrTable); array_pop($arrTable); if (count($arrTable)) { $strTable = implode('/', $arrTable) . '/' . $basename; } else { $strTable = $basename; } $this->midName = $strTable; } /** * 根据表名获取中间名 * @param $tableName * @return string */ protected function getMidName($tableName) { $arrTable = explode('_', $tableName); $basename = ucfirst($arrTable[count($arrTable) - 1]); $this->controllerModelClassName = $basename; array_shift($arrTable); array_pop($arrTable); if (count($arrTable)) { $strTable = implode('/', $arrTable) . '/' . $basename; } else { $strTable = $basename; } return $strTable; } /** * 根据表名获取类路径名称 * @param $table * @return string */ protected function getNameByTable($table) { $arrTable = explode('_', $table); $basename = ucfirst($arrTable[count($arrTable) - 1]); array_shift($arrTable);//del_db_prefix array_pop($arrTable); if (count($arrTable)) { $strTable = implode('\\', $arrTable) . '\\' . $basename; } else { $strTable = $basename; } return $strTable; } //设置需要生成的数据迁移文件名 protected function setMigrationFileName() { if ($this->needCreateTable) { $arrTable = explode('_', $this->tableName); array_shift($arrTable); foreach ($arrTable as $k => $name) { $arrTable[$k] = ucfirst($name); } $this->migrationClassName = implode('', $arrTable); $migrations = new Migrations(); $migration = $migrations->where('migration_name', '=', ucfirst($this->migrationClassName))->find(); if ($migration) { $this->migrationFileName = app()->getRootPath() . 'database' . DS . 'migrations' . DS . $migration->version . '_' . lcfirst($migration->migration_name) . '.php'; $migration->delete(); } else { $this->migrationFileName = app()->getRootPath() . 'database' . DS . 'migrations' . DS . date('YmdHis') . '_' . lcfirst(implode('', $arrTable)) . '.php'; } } } protected function filterMidName($midName) { if (substr($midName, 0, 6) === 'admin/') { return substr($midName, 6); } return $midName; } //设置所有需要生成的文件名 protected function setFileName() { $this->controllerFileName = app()->getAppPath() . 'controller' . DS . 'admin' . DS . $this->filterMidName($this->midName) . '.php'; $this->validateAddFileName = app()->getAppPath() . 'validate' . DS . 'admin' . DS . $this->filterMidName(strtolower($this->midName)) . DS . 'Add.php'; $this->validateEditFileName = app()->getAppPath() . 'validate' . DS . 'admin' . DS . $this->filterMidName(strtolower($this->midName)) . DS . 'Edit.php'; $this->modelFileName = app()->getAppPath() . 'model' . DS . $this->midName . '.php'; $this->jsFileName = app()->getRootPath() . 'public' . DS . 'static' . DS . 'admin' . DS . 'js' . DS . $this->filterMidName(strtolower($this->midName)) . '.js'; $this->recycleJsFileName = app()->getRootPath() . 'public' . DS . 'static' . DS . 'admin' . DS . 'js' . DS . $this->filterMidName(strtolower($this->midName)) . 'Recycle.js'; $this->htmlIndexFileName = app()->getRootPath() . 'public' . DS . 'admin' . DS . $this->filterMidName(strtolower($this->midName)) . DS . 'index.html'; $this->htmlAddFileName = app()->getRootPath() . 'public' . DS . 'admin' . DS . $this->filterMidName(strtolower($this->midName)) . DS . 'add.html'; $this->htmlEditFileName = app()->getRootPath() . 'public' . DS . 'admin' . DS . $this->filterMidName(strtolower($this->midName)) . DS . 'edit.html'; $this->htmlRecycleFileName = app()->getRootPath() . 'public' . DS . 'admin' . DS . $this->filterMidName(strtolower($this->midName)) . DS . 'recycle.html'; } //设置生成migration需要的参数 protected function setMigrationParam() { $tplName = 'migration' . DS . 'base'; $data['className'] = $this->migrationClassName; $data['tableName'] = str_replace(Config::get("database.connections." . Config::get("database.default") . ".prefix"), '', $this->tableName); $data['engine'] = $this->engine; $data['tableComment'] = $this->tableComment; $data['collation'] = $this->collation; $fields = ''; foreach ($this->fields as $field) { $fieldData['field'] = $field->field; $fieldData['dataType'] = $field->data_type; // $fieldData['limit'] = $field->limit; $fieldData['null'] = ($field->is_empty == 2) ? 0 : 1; if (in_array($field->data_type, ['integer', 'biginteger', 'boolean', 'decimal', 'float'])) { $field->default = intval($field->default); } $fieldData['default'] = (!in_array($field->data_type, ['text', 'datetime', 'timestamp'])) ? ' \'default\' => \'' . $field->default . '\',' : ' '; if ($field->form_type == 'radio' || $field->form_type == 'select') { $comment = ''; foreach ($field->addition['text'] as $k => $t) { $comment .= $field->addition['value'][$k] . '=' . $t . ','; } if (is_string($field->addition['default'])) { $comment .= '默认:' . $field->addition['default']; } $fieldData['comment'] = $field->comment . '.' . $comment; } elseif ($field->form_type == 'checkbox') { $comment = ''; foreach ($field->addition['text'] as $k => $t) { $comment .= $field->addition['value'][$k] . '=' . $t . ','; } $fieldData['comment'] = $field->comment . '.' . $comment . '默认:' . implode(',', $field->addition['default']); } elseif ($field->form_type == 'switch') { $comment = $field->addition['close_value'] . '=' . $field->addition['close_text'] . ',' . $field->addition['open_value'] . '=' . $field->addition['open_text'] . ',默认:' . (($field->addition['default_status'] === 'close') ? $field->addition['close_value'] : $field->addition['open_value']); $fieldData['comment'] = $field->comment . '.' . $comment; } elseif ($field->form_type == 'xm_select' && $field->addition['data_from_type'] == 'data') { $comment = ''; foreach ($field->addition['text'] as $k => $t) { $comment .= $field->addition['value'][$k] . '=' . $t . ','; } if ($field->addition['default']) { $comment .= '默认:' . implode(',', $field->addition['default']); } $fieldData['comment'] = $field->comment . '.' . $comment; } else { $fieldData['comment'] = $field->comment; } if (in_array($field->data_type, ["float", "decimal"])) { $fieldData['limitPrecisionScale'] = "'precision' => {$field->precision}, 'scale' => {$field->scale}, "; } elseif (in_array($field->data_type, ["text", "datetime", 'timestamp'])) { $fieldData['limitPrecisionScale'] = ''; } else { $fieldData['limitPrecisionScale'] = "'limit' => {$field->limit}, "; } $fields .= $this->getReplacedTpl('migration' . DS . 'field', $fieldData) . "\n\t\t\t"; } $data['fields'] = $fields; $this->migrationParam = ['tplName' => $tplName, 'data' => $data, 'fileName' => $this->migrationFileName]; } //生成数据迁移文件并执行数据库迁移命令,生成数据表 protected function createMigration() { if ($this->needCreateTable) { $this->writeToFile($this->migrationParam['tplName'], $this->migrationParam['data'], $this->migrationParam['fileName']); // 执行php think migrate:run命令是基于数据库迁移文件生成数据表 // 而最新的数据库迁移文件刚使用php程序生成,马上调用数据库迁移命令会读取不到最新刚生成的数据库迁移文件 // 使用clearstatcache函数没什么作用,所以此处停顿1秒 sleep(1); // 2>&1 是为了将标准错误输出存入output,如果不加,当有错误时output不会有错误输出,仅在windows下经过了测试 exec('php ' . app()->getRootPath() . '\think migrate:run 2>&1', $output, $resCode); if($resCode){ $filter = array_filter($output); $this->setError(array_pop($filter)); unlink($this->migrationParam['fileName']); return false; } } return true; } /** * 设置生成controller需要的参数 * [ * 'tplName'=>模板名, * 'data' => '执行替换模板的key=>value数组', * 'fileName' => '要生成的文件名' * ] */ protected function setControllerParam() { $tplName = 'controller' . DS . 'base'; $data['controllerNamespace'] = str_replace('/', '\\', dirname('app/controller/admin/' . $this->filterMidName($this->midName))); $data['tableComment'] = $this->tableComment; $data['modelName'] = strtolower(str_replace('/', '_', $this->midName)); $data['modelClassName'] = $this->controllerModelClassName; $data['modelNamespace'] = str_replace('/', '\\', dirname('app/model/' . $this->midName)); $data['controllerClassName'] = $this->controllerModelClassName; $data['indexFunction'] = $this->setIndexFunctionController(); $data['infoFunction'] = $this->setInfoFunctionController(); $data['recycleFunction'] = $this->setRecycleFunctionController(); $data['addFunction'] = $this->setAddFunctionController(); $data['editFunction'] = $this->setEditFunctionController(); $data['tableEditFunction'] = $this->setTableEditFunctionController(); $data['useAdminUserServiceFacade'] = ''; $data['uploadDomainPackage'] = ''; $data['useValidate'] = ''; foreach ($this->fields as $k => $v) { if ($v['form_type'] === 'admin_user_id') { $data['useAdminUserServiceFacade'] = "\nuse app\service\admin\UserServiceFacade;"; } if ($v['form_type'] == 'upload' || $v['form_type'] == 'editor') { $data['uploadDomainPackage'] = "\nuse laytp\library\UploadDomain;"; } if ($v['form_type'] == 'password') { $data['useValidate'] = "\nuse " . str_replace('/', '\\', 'app/validate/admin/' . strtolower(str_replace('/', '_', $this->filterMidName($this->midName))) . '/Add;'); $data['useValidate'] .= "\nuse " . str_replace('/', '\\', 'app/validate/admin/' . strtolower(str_replace('/', '_', $this->filterMidName($this->midName))) . '/Edit;'); if($v['addition']['save_type'] == 2){ $data['useValidate'] .= "\nuse laytp\\library\\Str;"; } } } $this->controllerParam = ['tplName' => $tplName, 'data' => $data, 'fileName' => $this->controllerFileName]; } //在index方法里,如果有关联模型,在查询时需要查询出关联模型数据 protected function setIndexFunctionController() { $relationIndexFunctionLt = 'controller' . DS . 'index'; $data = []; $data['withRelation'] = ""; $with = []; foreach ($this->fields as $k => $v) { if ($v['relation']['table']) { $with[] = $v['relation']['fun_name']; } if ($v['form_type'] === 'upload' && $v['addition']['multi'] === 'single') { $with[] = $v['field'] . '_file'; } } if ($with) { $data['withRelation'] = "->with(['" . implode("','", $with) . "'])"; } $indexFunctionController = $this->getReplacedTpl($relationIndexFunctionLt, $data); return $indexFunctionController; } //在info方法里,如果有上传组件,在查询的时候需要把文件相关的数据查询出来 protected function setInfoFunctionController() { $infoFunctionLt = 'controller' . DS . 'info'; $data = []; $data['withRelation'] = ""; $with = []; foreach ($this->fields as $k => $v) { if ($v['form_type'] === 'upload' && $v['addition']['multi'] === 'single') { $with[] = $v['field'] . '_file'; } } if ($with) { $data['withRelation'] = "->with(['" . implode("','", $with) . "'])"; } $infoFunctionController = $this->getReplacedTpl($infoFunctionLt, $data); return $infoFunctionController; } //在index方法里,如果有关联模型,在查询时需要查询出关联模型数据 protected function setRecycleFunctionController() { $recycleFunctionController = ''; $with = []; foreach ($this->fields as $k => $v) { if ($v['relation']['table']) { $with[] = $v['relation']['fun_name']; } } if ($with) { $relationIndexFunctionLt = 'controller' . DS . 'recycle'; $data['withRelation'] = "->with(['" . implode("','", $with) . "'])"; $recycleFunctionController = $this->getReplacedTpl($relationIndexFunctionLt, $data); } return $recycleFunctionController; } //富文本编辑器字段,在添加和编辑的控制器方法里面,所有链接要去掉前缀 protected function setAddFunctionController() { $validate = ''; $arrUploadDomainFields = []; $adminUserId = ''; $arrUnsetFields = []; foreach ($this->fields as $field) { if ($field->form_type == 'editor') { $arrUploadDomainFields[] = "\$post['{$field->field}'] = UploadDomain::delUploadDomain(\$post['{$field->field}'], '{$field->addition['upload_type']}');"; } if ($field->form_type == 'admin_user_id') { $adminUserId = "\$post['{$field->field}'] = UserServiceFacade::getUser()->id;"; } if ($field->field == 'password') { $validate = "\$validate = new Add();\n\t\tif(!\$validate->check(\$post)){\n\t\t\treturn \$this->error(\$validate->getError());\n\t\t}"; if($field->addition['save_type'] == 2){ if($field->is_empty == 2){ $arrUnsetFields[] = "if(!\$post['" . $field->field . "']){\n\t\t\tunset(\$post['" . $field->field . "']);\n\t\t}else{\n\t\t\tStr::createPassword(\$post['" . $field->field . "']);\n\t\t}"; }else{ $arrUnsetFields[] = "if(isset(\$post['" . $field->field . "']) && \$post['" . $field->field . "']) \$post['" . $field->field . "'] = Str::createPassword(\$post['" . $field->field . "']);"; } } } } if ($arrUploadDomainFields || $adminUserId || $validate || $arrUnsetFields) { $data['validate'] = $validate ? "\n\t\t" . $validate : ''; $data['adminUserId'] = $adminUserId ? "\n\t\t" . $adminUserId : ''; $data['uploadDomainFields'] = $arrUploadDomainFields ? "\n\t\t" . implode("\n\t\t", $arrUploadDomainFields) : ''; $data['unsetFields'] = $arrUnsetFields ? "\n\t\t" . implode("\n\t\t", $arrUnsetFields) : ''; $addFunctionLt = 'controller' . DS . 'add'; $addFunctionController = $this->getReplacedTpl($addFunctionLt, $data); return $addFunctionController; } else { return ''; } } //富文本编辑器字段,在添加和编辑的控制器方法里面,所有链接要去掉前缀 protected function setEditFunctionController() { $validate = ''; $arrUploadDomainFields = []; $adminUserId = ''; $arrUnsetFields = []; foreach ($this->fields as $k => $v) { if ($v['form_type'] == 'editor') { $arrUploadDomainFields[] = "\$post['{$v['field']}'] = UploadDomain::delUploadDomain(\$post['{$v['field']}'], '{$v['addition']['upload_type']}');"; } if ($v['form_type'] == 'admin_user_id') { $adminUserId = "\$post['{$v['field']}'] = UserServiceFacade::getUser()->id;"; } if ($v['field'] == 'password') { $validate = "\$validate = new Edit();\r\n\t\tif(!\$validate->check(\$post)){\r\n\t\t\treturn \$this->error(\$validate->getError());\r\n\t\t}"; if($v['addition']['save_type'] == 2){ $arrUnsetFields[] = "if(!\$post['" . $v['field'] . "']){\n\t\t\tunset(\$post['" . $v['field'] . "']);\n\t\t}else{\n\t\t\t\$post['" . $v['field'] . "'] = Str::createPassword(\$post['" . $v['field'] . "']);\n\t\t}"; }else{ $arrUnsetFields[] = 'if(!$post[\'' . $v['field'] . '\']) unset($post[\'' . $v['field'] . '\']);'; } } } if ($arrUploadDomainFields || $adminUserId || $validate || $arrUnsetFields) { $data['validate'] = $validate ? "\n\t\t" . $validate : ''; $data['adminUserId'] = $adminUserId ? "\n\t\t" . $adminUserId : ''; $data['uploadDomainFields'] = $arrUploadDomainFields ? "\n\t\t" . implode("\n\t\t", $arrUploadDomainFields) : ''; $data['unsetFields'] = $arrUnsetFields ? "\n\t\t" . implode("\n\t\t", $arrUnsetFields) : ''; $editFunctionLt = 'controller' . DS . 'edit'; $editFunctionController = $this->getReplacedTpl($editFunctionLt, $data); return $editFunctionController; } else { return ''; } } //设置表格编辑方法 protected function setTableEditFunctionController() { $functionContent = []; foreach ($this->fields as $k => $v) { if (($v['form_type'] == 'input' && isset($v['addition']['open_table_edit']) && $v['addition']['open_table_edit'] == 1) || $v['form_type'] == 'switch') { $data['field'] = $v['field']; $data['comment'] = $v['comment']; $data['funcName'] = ucfirst($this->underlineToCamel($v['field'])); $tableEditFunctionLt = 'controller' . DS . 'tableEdit'; $functionContent[] = $this->getReplacedTpl($tableEditFunctionLt, $data); } } $tableEditFunctionController = implode("\n\t\t", $functionContent); return $tableEditFunctionController; } //生成controller层 protected function createController() { $this->controllerParam['data']['hasSoftDel'] = "\n\tprotected \$hasSoftDel=0;//是否拥有软删除功能"; //是否拥有软删除功能 foreach ($this->fields as $k => $v) { if ($v['field'] == 'delete_time') { $this->controllerParam['data']['hasSoftDel'] = "\n\tprotected \$hasSoftDel=1;//是否拥有软删除功能"; break; } } $this->writeToFile($this->controllerParam['tplName'], $this->controllerParam['data'], $this->controllerParam['fileName']); } /** * 设置生成model需要的参数 * [ * 'tplName'=>模板名, * 'data' => '执行替换模板的key=>value数组', * 'fileName' => '要生成的文件名' * ] */ protected function setModelParam() { $tplName = 'model' . DS . 'base'; $arrTableName = explode('_', $this->tableName); $tablePrefix = $arrTableName['0'] . '_'; $data['tableName'] = ''; if ($tablePrefix != Config::get('database.connections.' . Config::get('database.default') . '.prefix')) { $data['tableName'] = 'protected $table = \'' . $this->tableName . '\';'; } $data['tableComment'] = $this->tableComment; $data['modelName'] = strtolower(str_replace('/', '_', $this->midName)); $data['modelClassName'] = $this->controllerModelClassName; $data['modelNamespace'] = str_replace('/', '\\', dirname('app/model/' . $this->midName)); $data['relationModel'] = $this->setRelationModel(); $data['autoTimeFormat'] = $this->autoTimeFormat(); $data['getAttrFun'] = $this->getAttrFun(); $this->modelParam = ['tplName' => $tplName, 'data' => $data, 'fileName' => $this->modelFileName]; } protected function setRelationModel() { $relationModelFunctionLt = 'model' . DS . 'relation_model_function'; $arrayRelationModel = []; $relationModel = ''; foreach ($this->fields as $k => $item) { if ($item['relation']['table']) { $data['relationFunctionName'] = $this->underlineToCamel($item['relation']['fun_name']); $data['relationType'] = $item['relation']['type']; $data['relationModelName'] = 'app\model\\' . $this->getNameByTable($item['relation']['table']); $data['foreignKey'] = $item['field']; $data['localKey'] = $item['relation']['field']; $arrayRelationModel[] = $this->getReplacedTpl($relationModelFunctionLt, $data); } if ($item['form_type'] === 'upload' && $item['addition']['multi'] === 'single') { $data['relationFunctionName'] = $this->underlineToCamel($item['field']) . 'File'; $data['relationType'] = 'belongsTo'; $data['relationModelName'] = 'app\model\Files'; $data['foreignKey'] = $item['field']; $data['localKey'] = 'id'; $arrayRelationModel[] = $this->getReplacedTpl($relationModelFunctionLt, $data); } } if ($arrayRelationModel) { $relationModel = implode("\n\n\t", $arrayRelationModel); } return $relationModel; } //时间选择器,int类型,自动类型转换 protected function autoTimeFormat() { $timeSet = []; foreach ($this->fields as $k => $v) { if ($v['form_type'] == 'laydate' && $v['data_type'] == 'integer') { if ($v['addition']['date_type'] == 'datetime') { $timeSet[$v['field']] = "\n\t\t" . '\'' . $v['field'] . '\' => \'timestamp:Y-m-d H:i:s\','; } else if ($v['addition']['date_type'] == 'month') { $timeSet[$v['field']] = "\n\t\t" . '\'' . $v['field'] . '\' => \'timestamp:Y-m\','; } else if ($v['addition']['date_type'] == 'date') { $timeSet[$v['field']] = "\n\t\t" . '\'' . $v['field'] . '\' => \'timestamp:Y-m-d\','; } } } if ($timeSet) { return 'protected $type = [' . implode('', $timeSet) . "\n\t];"; } else { return ''; } } protected function getAttrFun() { $fun = []; foreach ($this->fields as $k => $v) { if ($v['form_type'] == 'laydate' && $v['data_type'] == 'integer') { $fun[] = 'public function get' . ucfirst($this->underlineToCamel($v['field'])) . 'IntAttr($value, $data)' . "\n\t" . '{' . "\n\t\t" . 'return isset($data[\'' . $v['field'] . '\']) ? $data[\'' . $v['field'] . '\'] : 0;' . "\n\t" . '}'; } if ($v['form_type'] == 'laydate' && $v['data_type'] == 'datetime') { $fun[] = 'public function get' . ucfirst($this->underlineToCamel($v['field'])) . 'IntAttr($value, $data)' . "\n\t" . '{' . "\n\t\t" . 'return isset($data[\'' . $v['field'] . '\']) ? strtotime($data[\'' . $v['field'] . '\']) : 0;' . "\n\t" . '}'; } if ($v['form_type'] == 'upload' && $v['addition']['multi'] == 'multi') { $fun[] = 'public function get' . ucfirst($this->underlineToCamel($v['field'])) . 'FileAttr($value, $data)' . "\n\t" . '{' . "\n\t\t" . 'return (isset($data[\'' . $v['field'] . '\']) && $data[\'' . $v['field'] . '\']) ? UploadDomain::multiJoin($data[\'' . $v['field'] . '\']) : \'\';' . "\n\t" . '}'; } if ($v['form_type'] == 'editor') { if ($v['addition']['upload_type'] != 'local') { $fun[] = 'public function get' . ucfirst($this->underlineToCamel($v['field'])) . 'Attr($value, $data)' . "\n\t" . '{' . "\n\t\t" . 'return $value ? UploadDomain::addUploadDomain($value, \'' . $v['addition']['upload_type'] . '\') : \'\';' . "\n\t" . '}'; } else { $fun[] = 'public function get' . ucfirst($this->underlineToCamel($v['field'])) . 'Attr($value, $data)' . "\n\t" . '{' . "\n\t\t" . 'return $value ? UploadDomain::addUploadDomain($value) : \'\';' . "\n\t" . '}'; } } } if ($fun) { return implode("\n\n\t", $fun); } else { return ''; } } protected function createModel() { //是否拥有软删除功能 $this->modelParam['data']['softDelPackage'] = ""; $this->modelParam['data']['useSoftDel'] = ""; $this->modelParam['data']['defaultSoftDelete'] = ""; $this->modelParam['data']['uploadDomainPackage'] = ""; $this->modelParam['data']['append'] = ""; $append = []; foreach ($this->fields as $k => $v) { if ($v['field'] == 'delete_time') { $this->modelParam['data']['softDelPackage'] = "\nuse think\model\concern\SoftDelete;"; $this->modelParam['data']['useSoftDel'] = "\n\tuse SoftDelete;"; if ($v['data_type'] === 'datetime' || $v['data_type'] === 'timestamp') { $this->modelParam['data']['defaultSoftDelete'] = ""; } else if ($v['data_type'] === 'integer') { $this->modelParam['data']['defaultSoftDelete'] = "\n\tprotected \$defaultSoftDelete=0;"; } } if (($v['form_type'] == 'upload' && $v['addition']['multi'] == 'multi') || $v['form_type'] == 'editor') { $this->modelParam['data']['uploadDomainPackage'] = "\nuse laytp\library\UploadDomain;"; } if (($v['form_type'] == 'upload' && $v['addition']['multi'] == 'multi')) { $append[] = '\'' . $v['field'] . '_file\''; } if ($v['form_type'] == 'laydate') { $append[] = '\'' . $v['field'] . '_int\''; } } if ($append) { $this->modelParam['data']['append'] = implode(',', $append); } $this->writeToFile($this->modelParam['tplName'], $this->modelParam['data'], $this->modelParam['fileName']); } protected function setJsParam() { $apiPrefix = $this->compatibleApiRoute(); $tplName = 'js' . DS . 'index'; $cols = "{type:'checkbox',fixed:'left'}\n\t\t\t\t"; $recycleCols = "{type:'checkbox',fixed:'left'}\n\t\t\t\t"; $hasFirstCols = true;//是否已经有了正常的第一行数据 //是否隐藏主键列 if ($this->isHidePk != 1) { $hasFirstCols = true; $temp = ",{field:'id',title:'ID',align:'center',width:80,fixed:'left'}"; $cols .= $temp; $recycleCols .= $temp; } else { $temp = "//,{field:'id',title:'ID',align:'center',width:80}"; $cols .= $temp; $recycleCols .= $temp; } //是否生成序号列 if ($this->isCreateNumber == 1) { if ($hasFirstCols) { $temp = "\n\t\t\t\t,{field:'layui_number',title:'序号',align:'center',width:80,type:'numbers'}"; $cols .= $temp; $recycleCols .= $temp; } else { $temp = "\t\t\t\t{field:'layui_number',title:'序号',align:'center',width:80,type:'numbers'}"; $cols .= $temp; $recycleCols .= $temp; } if (!$hasFirstCols) $hasFirstCols = true; } foreach ($this->fields as $k => $v) { // if ($v['table_show'] == 2) continue; if (!$hasFirstCols) { $hasFirstCols = true; $temp = "\t\t\t\t{field:'{$v['field']}',title:'{$v['comment']}'"; $recycleTemp = "\t\t\t\t{field:'{$v['field']}',title:'{$v['comment']}'"; } else { $temp = "\n\t\t\t\t,{field:'{$v['field']}',title:'{$v['comment']}'"; $recycleTemp = "\n\t\t\t\t,{field:'{$v['field']}',title:'{$v['comment']}'"; } if ($v['cell_width']) { $temp .= ",width:{$v['cell_width']}"; $recycleTemp .= ",width:{$v['cell_width']}"; } $temp .= ",align:'center'"; $recycleTemp .= ",align:'center'"; //表头排序 if ($v['is_thead_sort'] == 1) { $temp .= ",sort:true"; $recycleTemp .= ",sort:true"; } //关联模型js渲染 if ($v['relation']['table'] && $v['relation']['show_field']) { if ($v['form_type'] === 'xm_select') { if (isset($v['addition']['single_multi_type']) && $v['addition']['single_multi_type'] === 'single') { $templet = "{{# if(d." . $v['relation']['fun_name'] . "){ }}{{d." . $v['relation']['fun_name'] . "." . $v['relation']['show_field'] . "}}{{# }else{ }}-{{# } }}"; $temp .= ",templet:'
" . $templet . "
'"; $recycleTemp .= ",templet:'
" . $templet . "
'"; } } else { $templet = "{{# if(d." . $v['relation']['fun_name'] . "){ }}{{d." . $v['relation']['fun_name'] . "." . $v['relation']['show_field'] . "}}{{# }else{ }}-{{# } }}"; $temp .= ",templet:'
" . $templet . "
'"; $recycleTemp .= ",templet:'
" . $templet . "
'"; } } //单行输入框,开启了表格编辑,需要渲染成editInput模板,没有开启的话要转义展示,避免XSS if ($v['form_type'] == 'input') { if (isset($v['addition']['open_table_edit']) && $v['addition']['open_table_edit'] == 1) { $editInputUrl = $apiPrefix . '/set' . ucfirst($this->underlineToCamel($v['field'])); $temp .= ",templet:function(d){ return laytpForm.tableForm.editInput('{$v['field']}',d,'{$editInputUrl}'); }"; $recycleTemp .= ",templet:function(d){ return laytpForm.tableForm.recycleEditInput('{$v['field']}',d,'{$editInputUrl}'); }"; } else { // $temp .= ",templet:function(d){ // return layui.laytpl('{{=d.{$v['field']}}}').render({{$v['field']}:d.{$v['field']}}); // }"; // $recycleTemp .= ",templet:function(d){ // return layui.laytpl('{{=d.{$v['field']}}}').render({{$v['field']}:d.{$v['field']}}); // }"; } } //文本域要转义展示,避免XSS // if ($v['form_type'] == 'textarea') { // $temp .= ",templet:function(d){ // return layui.laytpl('{{=d.{$v['field']}}}').render({{$v['field']}:d.{$v['field']}}); // }"; // $recycleTemp .= ",templet:function(d){ // return layui.laytpl('{{=d.{$v['field']}}}').render({{$v['field']}:d.{$v['field']}}); // }"; // } //渲染单选按钮,单选按钮渲染成status模板 if ($v['form_type'] == 'radio') { $items = $v['addition']; $jsonArr['value'] = $items['value']; $jsonArr['text'] = $items['text']; $jsonObj = json_encode($jsonArr, JSON_UNESCAPED_UNICODE); $temp .= ",templet:function(d){ return laytp.tableFormatter.status('{$v['field']}',d.{$v['field']},{$jsonObj}); }"; $recycleTemp .= ",templet:function(d){ return laytp.tableFormatter.status('{$v['field']}',d.{$v['field']},{$jsonObj}); }"; } //渲染开关按钮,开关按钮渲染成开关 if ($v['form_type'] == 'switch') { $items = $v['addition']; $temp .= ",templet:function(d){ return laytpForm.tableForm.switch(\"{$v['field']}\", d, { \"open\": {\"value\": {$items['open_value']}, \"text\": \"{$items['open_text']}\"}, \"close\": {\"value\": {$items['close_value']}, \"text\": \"{$items['close_text']}\"} }); }"; $recycleTemp .= ",templet:function(d){ return laytpForm.tableForm.recycleSwitch(\"{$v['field']}\", d, { \"open\": {\"value\": {$items['open_value']}, \"text\": \"{$items['open_text']}\"}, \"close\": {\"value\": {$items['close_value']}, \"text\": \"{$items['close_text']}\"} }); }"; } //渲染下拉框,下拉框渲染成status模板 if ($v['form_type'] == 'select') { $jsonObj = json_encode($v['addition'], JSON_UNESCAPED_UNICODE); $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.status('{$v['field']}',d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.status('{$v['field']}',d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; } //复选框渲染成flag的模板 if ($v['form_type'] == 'checkbox') { $jsonObj = json_encode($v['addition'], JSON_UNESCAPED_UNICODE); $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.flag(d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.flag(d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; } //xmSelect,数据来源=data,单选,渲染成status if ($v['form_type'] == 'xm_select' && $v['addition']['data_from_type'] == 'data' && $v['addition']['single_multi_type'] == 'single') { $jsonArr['value'] = $v['addition']['value']; $jsonArr['text'] = $v['addition']['text']; $jsonArr['default'] = $v['addition']['default']; $jsonObj = json_encode($jsonArr, JSON_UNESCAPED_UNICODE); $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.status('{$v['field']}',d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.status('{$v['field']}',d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; } //xmSelect,数据来源=data,多选,渲染成flag if ($v['form_type'] == 'xm_select' && $v['addition']['data_from_type'] == 'data' && $v['addition']['single_multi_type'] == 'multi') { $jsonArr['value'] = $v['addition']['value']; $jsonArr['text'] = $v['addition']['text']; $jsonArr['default'] = $v['addition']['default']; $jsonObj = json_encode($jsonArr, JSON_UNESCAPED_UNICODE); $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.flag(d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.flag(d.{$v['field']},{$jsonObj});\n\t\t\t\t}"; } //image模板 if ($v['form_type'] == 'upload' && $v['addition']['accept'] == 'image') { if ($v['addition']['multi'] == 'single') { $temp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.images(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.images(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; } else { $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.images(d.{$v['field']}_file.path);\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.images(d.{$v['field']}_file.path);\n\t\t\t\t}"; } } //video模板 if ($v['form_type'] == 'upload' && $v['addition']['accept'] == 'video') { if ($v['addition']['multi'] == 'single') { $temp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.video(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.video(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; } else { $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.video(d.{$v['field']}_file.path);\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.video(d.{$v['field']}_file.path);\n\t\t\t\t}"; } } //audio模板 if ($v['form_type'] == 'upload' && $v['addition']['accept'] == 'audio') { if ($v['addition']['multi'] == 'single') { $temp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.audio(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.audio(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; } else { $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.audio(d.{$v['field']}_file.path);\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.audio(d.{$v['field']}_file.path);\n\t\t\t\t}"; } } //file模板 if ($v['form_type'] == 'upload' && $v['addition']['accept'] == 'file') { if ($v['addition']['multi'] == 'single') { $temp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.file(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn d.{$v['field']}_file ? laytp.tableFormatter.file(d.{$v['field']}_file.path) : \"\";\n\t\t\t\t}"; } else { $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.file(d.{$v['field']}_file.path);\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.file(d.{$v['field']}_file.path);\n\t\t\t\t}"; } } //colorPicker模板 if ($v['form_type'] == 'color_picker') { $temp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.colorPicker(d.{$v['field']});\n\t\t\t\t}"; $recycleTemp .= ",templet:function(d){\n\t\t\t\t\treturn laytp.tableFormatter.colorPicker(d.{$v['field']});\n\t\t\t\t}"; } $temp .= "}"; $recycleTemp .= "}"; if ($v['table_show'] == 1) $cols .= $temp; $recycleCols .= $recycleTemp; } $data['cols'] = $cols; $data['cellMinWidth'] = 120; $data['apiPrefix'] = $this->compatibleApiRoute(); $data['htmlPrefix'] = $this->compatibleHtmlPath(); $this->jsParam = ['tplName' => $tplName, 'data' => $data, 'fileName' => $this->jsFileName]; $data['recycleCols'] = $recycleCols; $this->recycleJsParam = ['tplName' => 'js' . DS . 'recycle', 'data' => $data, 'fileName' => $this->recycleJsFileName]; } public function compatibleApiRoute($midName = false) { if (!$midName) { $midName = strtolower($this->midName); } else { $midName = strtolower($midName); } if ($midName === "user") { return "/admin.api.user"; } if (substr($midName, 0, 5) . '.' != 'admin.') { return '/admin.' . str_replace('/', '.', $midName); } else { return '/' . str_replace('/', '.', $midName); } } public function compatibleHtmlPath() { $midName = strtolower($this->midName); if (substr($midName, 0, 5) != 'admin/') { return '/admin/' . strtolower($midName); } else { return '/' . strtolower($midName); } } /** * 获取一个数组,根据传入的参数,这个参数string的格式类似于:0=游泳,1=下棋,2=游戏,3=乒乓球,4=羽毛,5=跑步,6=爬山,7=美食,default=0;1;2 * @param $string * @return array */ public function getArrayByString($string) { $items = explode(",", $string); $radio_items = [];//待选项数组 foreach ($items as $k => $v) { $temp = explode('=', $v); if ($temp[0] != 'default') { $radio_items[$temp[0]] = $temp[1]; } } return $radio_items; } //生成js文件 protected function createJs() { $this->writeToFile($this->jsParam['tplName'], $this->jsParam['data'], $this->jsParam['fileName']); if ($this->hasSoftDel) { $this->writeToFile($this->recycleJsParam['tplName'], $this->recycleJsParam['data'], $this->recycleJsParam['fileName']); } } protected function setHtmlParam() { $indexTplName = 'html' . DS . 'index'; $indexData['jsFileName'] = $this->filterMidName(strtolower($this->midName)) . '.js'; $indexSearchForm = []; $recycleSearchForm = []; $linkageSelectSearchHtml = []; $recycleLinkageSelectSearchHtml = []; $unSearchType = ['password', 'upload', 'color_picker']; foreach ($this->fields as $k => $v) { if (!in_array($v['form_type'], $unSearchType)) { if (in_array($v['form_type'], ['linkage_select', 'linkage_xm_select'])) { if ($v['search_show'] == 1) { $linkageSelectSearchHtml[$v['form_type']][$v['addition']['group_name']][] = $this->getSearchFormContent($v); } $recycleLinkageSelectSearchHtml[$v['form_type']][$v['addition']['group_name']][] = $this->getSearchFormContent($v); } else { $searchItemContent = $this->getSearchFormContent($v); if ($v['search_show'] == 1) { $indexSearchForm[] = $this->getSearchFormItem($v, $searchItemContent); } $recycleSearchForm[] = $this->getSearchFormItem($v, $searchItemContent); } } } if (count($linkageSelectSearchHtml)) { foreach ($linkageSelectSearchHtml as $formType => $groupList) { foreach ($groupList as $groupName => $item) { $indexSearchForm[] = $this->getLinkageSelectSearchFormGroup($groupName, join("\n\t\t\t\t", $item)); } } } if (count($recycleLinkageSelectSearchHtml)) { foreach ($recycleLinkageSelectSearchHtml as $formType => $groupList) { foreach ($groupList as $groupName => $item) { $recycleSearchForm[] = $this->getLinkageSelectSearchFormGroup($groupName, join("\n\t\t\t\t", $item)); } } } $indexData['searchItemId'] = ($this->isHidePk == 1) ? '' : '
'; $indexData['searchForm'] = implode("\n\n\t\t\t", $indexSearchForm); $indexData['apiPrefix'] = $this->compatibleApiRoute(); $indexData['htmlPrefix'] = $this->compatibleHtmlPath(); $this->htmlIndexParam = ['tplName' => $indexTplName, 'data' => $indexData, 'fileName' => $this->htmlIndexFileName]; $addData = []; $editData = []; // $detailData = []; $recycleData = []; $linkageSelectAddHtml = []; $linkageSelectEditHtml = []; foreach ($this->fields as $k => $v) { if (in_array($v['form_type'], ['linkage_select', 'linkage_xm_select'])) { if ($v['add_show'] == 1) { $linkageSelectAddHtml[$v['form_type']][$v['addition']['group_name']][] = $this->getFormItem($v, 'add'); } if ($v['edit_show'] == 1) { $linkageSelectEditHtml[$v['form_type']][$v['addition']['group_name']][] = $this->getFormItem($v, 'edit'); } } else if (in_array($v['form_type'], ['admin_user_id'])) { // $addData[] = $this->getFormItem($v, 'add'); // $editData[] = $this->getFormItem($v, 'edit'); } else { if ($v['add_show'] == 1) { $addItemContent = $this->getFormItem($v, 'add'); $addData[] = $this->getFormGroup($v['comment'], $addItemContent, $v['is_empty']); if ($v['form_type'] == 'password' && $v['addition']['re_password']) { $reV = $v->toArray(); $reV['field'] = 're_' . $reV['field']; $addItemContent = $this->getFormItem($reV, 'add'); $addData[] = $this->getFormGroup('重复' . $reV['comment'], $addItemContent, $reV['is_empty']); } } if ($v['edit_show'] == 1) { $editItemContent = $this->getFormItem($v, 'edit'); $editData[] = $this->getFormGroup($v['comment'], $editItemContent, $v['is_empty']); if ($v['form_type'] == 'password' && $v['addition']['re_password']) { $reV = $v->toArray(); $reV['field'] = 're_' . $reV['field']; $addItemContent = $this->getFormItem($reV, 'edit'); $editData[] = $this->getFormGroup('重复' . $reV['comment'], $addItemContent, $reV['is_empty']); } } } // $detailData[] = $this->getDetailItem($v, $this->getDetailContent($v)); } if (count($linkageSelectAddHtml)) { foreach ($linkageSelectAddHtml as $formType => $groupList) { foreach ($groupList as $groupName => $item) { $addData[] = $this->getFormGroup($groupName, join("\n\t\t\t\t\t\t", $item), 1); } } } if (count($linkageSelectEditHtml)) { foreach ($linkageSelectEditHtml as $formType => $groupList) { foreach ($groupList as $groupName => $item) { $editData[] = $this->getFormGroup($groupName, join("\n\t\t\t\t\t\t", $item), 1); } } } $addTplName = 'html' . DS . 'add'; $addForm['formContent'] = implode("\n\n", $addData); $addForm['action'] = $this->compatibleApiRoute() . '/add'; $this->htmlAddParam = ['tplName' => $addTplName, 'data' => $addForm, 'fileName' => $this->htmlAddFileName]; $editTplName = 'html' . DS . 'edit'; $editForm['formContent'] = implode("\n\n", $editData); $editForm['action'] = $this->compatibleApiRoute() . '/edit'; $editForm['infoAction'] = $this->compatibleApiRoute() . '/info'; $this->htmlEditParam = ['tplName' => $editTplName, 'data' => $editForm, 'fileName' => $this->htmlEditFileName]; // $detailTplName = 'html' . DS . 'detail'; // $detailHtmlData['tableContent'] = implode("\n", $detailData); // $this->htmlDetailParam = ['tplName' => $detailTplName, 'data' => $detailHtmlData, 'fileName' => $this->htmlDetailFileName]; $recycleTplName = 'html' . DS . 'recycle'; $recycleData['searchForm'] = implode("\n\n\t\t", $recycleSearchForm); $recycleData['jsFileName'] = strtolower($this->midName) . 'Recycle.js'; $recycleData['apiPrefix'] = $this->compatibleApiRoute(); $recycleData['htmlPrefix'] = $this->compatibleHtmlPath(); $this->htmlRecycleParam = ['tplName' => $recycleTplName, 'data' => $recycleData, 'fileName' => $this->htmlRecycleFileName]; } protected function getDetailItem($info, $content) { return << {$info['comment']} {$content} EOD; } protected function getDetailContent($info) { //关联模型 if ($info['relation']['table'] && $info['relation']['show_field']) { return "{{d." . $info['relation']['fun_name'] . "." . $info['relation']['show_field'] . "}}"; } else if ($info['form_type'] === 'radio') { $additionArr = []; foreach ($info['addition']['value'] as $k => $item) { $additionArr[$item] = $info['addition']['text'][$k]; } $additionJson = json_encode($additionArr, JSON_UNESCAPED_UNICODE); return "\n\t\t\t\t{{# let " . $info['field'] . "Json = " . $additionJson . " }}\n\t\t\t\t{{" . $info['field'] . "Json[d." . $info['field'] . "]}}\n\t\t\t"; } else if ($info['form_type'] === 'switch') { $additionArr = [ $info['addition']['close_value'] => $info['addition']['close_text'], $info['addition']['open_value'] => $info['addition']['open_text'], ]; $additionJson = json_encode($additionArr, JSON_UNESCAPED_UNICODE); return "\n\t\t\t\t{{# let " . $info['field'] . "Json = " . $additionJson . " }}\n\t\t\t\t{{" . $info['field'] . "Json[d." . $info['field'] . "]}}\n\t\t\t"; } else if ($info['form_type'] === 'checkbox') { $custom = ["#FF5722", "#009688", "#FFB800", "#2F4056", "#1E9FFF", "#393D49", "#999999", "#0b1bf8", "#7a0bf8", "#f00bf8", "#5FB878", "#1E9FFF", "#2F4056"]; $additionArr = []; foreach ($info['addition']['value'] as $k => $item) { $additionArr[$item] = [ 'text' => $info['addition']['text'][$k], 'color' => $custom[$k], ]; } $additionJson = json_encode($additionArr, JSON_UNESCAPED_UNICODE); $additionJson = substr($additionJson, 0, -1) . ' ' . substr($additionJson, -1, 1); return "\n\t\t\t\t{{# let " . $info['field'] . "Json = " . $additionJson . " }}\n\t\t\t\t" . "{{# let " . $info['field'] . "Arr = d." . $info['field'] . ".split(\",\"), " . $info['field'] . "K}}\n\t\t\t\t" . "{{# for(" . $info['field'] . "K in " . $info['field'] . "Arr){ }}\n\t\t\t\t\t" . "{{" . $info['field'] . "Json[" . $info['field'] . "Arr[" . $info['field'] . "K]]['text']}}\n\t\t\t\t" . "{{# } }}\n\t\t\t"; } else if ($info['form_type'] === 'select') { $additionArr = []; foreach ($info['addition']['value'] as $k => $item) { $additionArr[$item] = $info['addition']['text'][$k]; } $additionJson = json_encode($additionArr, JSON_UNESCAPED_UNICODE); return "\n\t\t\t\t{{# let " . $info['field'] . "Json = " . $additionJson . " }}\n\t\t\t\t{{" . $info['field'] . "Json[d." . $info['field'] . "]}}\n\t\t\t"; } else if ($info['form_type'] === 'color_picker') { return "  \n\t\t\t"; } else if ($info['form_type'] === 'upload') { if ($info['addition']['accept'] === 'image') { if ($info['addition']['multi'] === 'single') { return "\n\t\t\t\t" . "\n\t\t\t\t\n\t\t\t"; } if ($info['addition']['multi'] === 'multi') { return "\n\t\t\t\t{{# var " . $info['field'] . "Arr = d." . $info['field'] . ".split(\", \"), " . $info['field'] . "K}}" . "\n\t\t\t\t{{# for(" . $info['field'] . "K in " . $info['field'] . "Arr){ }}" . "\n\t\t\t\t\t" . "\n\t\t\t\t\t\n\t\t\t\t" . "{{# } }}\n\t\t\t"; } } else if ($info['addition']['accept'] === 'video') { if ($info['addition']['multi'] === 'single') { return "\n\t\t\t\t视频\n\t\t\t"; } if ($info['addition']['multi'] === 'multi') { return "\n\t\t\t\t{{# var " . $info['field'] . "Arr = d." . $info['field'] . ".split(\", \"), " . $info['field'] . "K}}\n\t\t\t\t" . "{{# for(" . $info['field'] . "K in " . $info['field'] . "Arr){ }}\n\t\t\t\t\t" . "视频{{parseInt(" . $info['field'] . "K) + 1}}\n\t\t\t\t" . "{{# } }}\n\t\t\t"; } } else if ($info['addition']['accept'] === 'audio') { if ($info['addition']['multi'] === 'single') { return "\n\t\t\t\t\n\t\t\t"; } if ($info['addition']['multi'] === 'multi') { return "\n\t\t\t\t{{# var " . $info['field'] . "Arr = d." . $info['field'] . ".split(\", \"), " . $info['field'] . "K}}" . "\n\t\t\t\t{{# for(" . $info['field'] . "K in " . $info['field'] . "Arr){ }}" . "\n\t\t\t\t\t" . "\n\t\t\t\t\t" . "\n\t\t\t\t{{# } }}\n\t\t\t"; } } else if ($info['addition']['accept'] === 'file') { if ($info['addition']['multi'] === 'single') { return "\n\t\t\t\t文件\n\t\t\t"; } if ($info['addition']['multi'] === 'multi') { return "\n\t\t\t\t{{# var " . $info['field'] . "Arr = d." . $info['field'] . ".split(\", \"), " . $info['field'] . "K}}\n\t\t\t\t" . "{{# for(" . $info['field'] . "K in " . $info['field'] . "Arr){ }}\n\t\t\t\t\t" . "文件{{parseInt(" . $info['field'] . "K) + 1}}\n\t\t\t\t" . "{{# } }}\n\t\t\t"; } } } else if ($info['form_type'] === 'editor') { if ($info['addition']['type'] === 'ueditor') { return "\n\t\t\t\t\n\t\t\t"; } } return "{{d." . $info['field'] . "}}"; } //生成html模板文件 protected function createHtml() { $this->writeToFile($this->htmlIndexParam['tplName'], $this->htmlIndexParam['data'], $this->htmlIndexParam['fileName']); $this->writeToFile($this->htmlAddParam['tplName'], $this->htmlAddParam['data'], $this->htmlAddParam['fileName']); $this->writeToFile($this->htmlEditParam['tplName'], $this->htmlEditParam['data'], $this->htmlEditParam['fileName']); // $this->writeToFile($this->htmlDetailParam['tplName'], $this->htmlDetailParam['data'], $this->htmlDetailParam['fileName']); //是否拥有软删除功能 foreach ($this->fields as $k => $v) { if ($v->field == 'delete_time') { $this->writeToFile($this->htmlRecycleParam['tplName'], $this->htmlRecycleParam['data'], $this->htmlRecycleParam['fileName']); break; } } } protected function getFormItem($info, $type = 'add') { $func = 'get' . ucfirst($this->underlineToCamel($info['form_type'])) . 'Html'; return $this->$func($info, $type); } /** * 获取表单分组数据 * @param string $field * @param string $content * @param integer $isEmpty * @return string */ protected function getFormGroup($field, $content, $isEmpty) { if ($isEmpty != 1) { $requiredHtml = " * "; } else { $requiredHtml = ""; } return << \t\t\t\t \t\t\t\t
\t\t\t{$content} \t\t\t\t
\t\t\t\t EOD; } protected function getSearchFormContent($info) { $func = 'getSearch' . ucfirst($this->underlineToCamel($info['form_type'])) . 'Html'; return $this->$func($info); } protected function getSearchFormItem($info, $content) { $fieldComment = $info['comment']; return <<
{$content}
EOD; } protected function getLinkageSelectSearchFormGroup($field, $content) { return << {$content} EOD; } protected function getLinkageXmSelectSearchFormGroup($field, $content) { return << {$content} EOD; } /** * 接下来是html的各种控件模板内容生成,比如input、select、upload等等 */ /** * 获取input需要生成的html,在生成add和edit表单的时候可以用到 * @param $info * @param $type string 类型,add或者edit * @return string */ protected function getInputHtml($info, $type) { $name = 'html' . DS . $type . DS . 'input'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; if ($info['is_empty'] == 2) { $data['verify'] = $info['addition']['verify'] ? 'required|' . $info['addition']['verify'] : 'required'; } else { $data['verify'] = $info['addition']['verify']; } $data['defaultValue'] = ($info['default'] === "") ? "" : " value=\"" . $info['default'] . "\""; return $this->getReplacedTpl($name, $data); } /** * 获取input需要生成的html,在生成搜索表单时用到 * @param $info * @return string */ protected function getSearchInputHtml($info) { $name = 'html' . DS . 'search' . DS . 'input'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } /** * 获取password需要生成的html,在生成add和edit表单的时候可以用到 * @param $info * @param $type string 类型,add或者edit * @return string */ protected function getPasswordHtml($info, $type) { $name = 'html' . DS . $type . DS . 'password'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; if ($type == 'edit') { $data['comment'] .= ',留空表示不修改'; } if ($info['is_empty'] == 2) { $data['verify'] = 'required'; } else { $data['verify'] = ''; } if ($info['addition']['input_type'] == '1') { $data['input_type'] = 'text'; } else { $data['input_type'] = 'password'; } $data['defaultValue'] = ($info['default'] === "") ? "" : " value=\"" . $info['default'] . "\""; return $this->getReplacedTpl($name, $data); } /** * admin_id类型模板 * @param $info * @param $type * @return string */ protected function getAdminUserIdHtml($info, $type) { $name = 'html' . DS . $type . DS . 'admin_id'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } /** * admin_id类型模板 * @param $info * @return string */ protected function getSearchAdminUserIdHtml($info) { $name = 'html' . DS . 'search' . DS . 'admin_id'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } /** * 获取input需要生成的html,在生成add和edit表单的时候可以用到 * @param $info * @param $type string 类型,add或者edit * @return string */ protected function getTextareaHtml($info, $type) { $name = 'html' . DS . $type . DS . 'textarea'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $data['verify'] = $info['is_empty'] == 1 ? '' : 'required'; return $this->getReplacedTpl($name, $data); } /** * 获取input需要生成的html,在生成搜索表单时用到 * @param $info * @return string */ protected function getSearchTextareaHtml($info) { $name = 'html' . DS . 'search' . DS . 'textarea'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } /** * 获取input需要生成的html,在生成add和edit表单的时候可以用到 * @param $info * @param $type string 类型,add或者edit * @return string */ protected function getRadioHtml($info, $type) { $items = $info['addition']; $name = 'html' . DS . $type . DS . 'radio'; $radioHtml = ''; foreach ($items['value'] as $k => $v) { $tempData['field'] = $info['field']; $tempData['value'] = $items['value'][$k]; $tempData['title'] = $items['text'][$k]; $tempData['checkedStatus'] = ($items['value'][$k] == $items['default']) ? 'checked="checked"' : ''; $radioHtml .= $this->getReplacedTpl($name, $tempData) . "\n\t\t\t\t\t\t"; } $radioHtml = rtrim($radioHtml, "\n\t\t\t"); // $this->set_model_array_const($info['field_name'], $model_array_const); return $radioHtml; } protected function getSearchRadioHtml($info) { $name = 'html' . DS . 'search' . DS . 'radio'; $data['field'] = $info['field']; $items = $info['addition']; $options = ''; foreach ($items['value'] as $k => $v) { $options .= "\t\t\t\t\t\t" . '' . "\n"; } $options = "\t\t\t\t" . '' . "\n" . rtrim($options, "\n"); $data['options'] = $options; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } protected function getSwitchHtml($info, $type) { $items = $info['addition']; $name = 'html' . DS . $type . DS . 'switch'; $data['field'] = $info['field']; $data['close_value'] = $items['close_value']; $data['open_value'] = $items['open_value']; $data['checked_status'] = ($items['default_status'] == 'open') ? 'checked="checked"' : ''; $data['lay_text'] = $items['open_text'] . '|' . $items['close_text']; return $this->getReplacedTpl($name, $data); } protected function getSearchSwitchHtml($info) { $name = 'html' . DS . 'search' . DS . 'radio'; $data['field'] = $info['field']; $items = $info['addition']; $options = ''; $options .= "\t\t\t\t\t\t" . '' . "\n"; $options .= "\t\t\t\t\t\t" . '' . "\n"; $data['options'] = $options; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } protected function getSearchCheckboxHtml($info) { $name = 'html' . DS . 'search' . DS . 'checkbox'; $data['field'] = $info['field']; $items = $info['addition']; $data['max'] = count($items); $optionItems = []; // $model_array_const = []; foreach ($items['value'] as $k => $v) { $optionItems[] = ['value' => $items['value'][$k], 'name' => $items['text'][$k]]; // $model_array_const[(string)$temp[0]] = $temp[1]; } // $data['source'] = str_replace("\"", "'", json_encode($optionItems, JSON_UNESCAPED_UNICODE)); $data['source'] = json_encode($optionItems, JSON_UNESCAPED_UNICODE); // $this->set_controller_array_const($info['field_name'], $model_array_const); return $this->getReplacedTpl($name, $data); } protected function getCheckboxHtml($info, $type) { $name = 'html' . DS . $type . DS . 'checkbox'; $data['field'] = $info['field']; $items = $info['addition']; $optionItems = []; $checkboxHtml = ''; foreach ($items['value'] as $k => $v) { $optionItems[] = ['value' => $items['value'][$k], 'text' => $items['text'][$k]]; } $defaultValueArr = isset($items['default']) ? $items['default'] : []; foreach ($optionItems as $k => $v) { if ($k == 0 && $type == 'edit') { $checkboxHtml .= "{{# var " . $info['field'] . "ValueArr = d." . $info['field'] . ".toString().split(','); }}\n\t\t\t\t\t\t"; } if ($type == 'add') { $data['checked'] = in_array($v['value'], $defaultValueArr) ? 'checked="checked"' : ''; } $data['value'] = $v['value']; $data['text'] = $v['text']; $checkboxHtml .= $this->getReplacedTpl($name, $data) . "\n\t\t\t\t\t\t"; } $checkboxHtml = rtrim($checkboxHtml, "\n\t\t\t\t\t\t"); // $this->set_model_array_const($info['field_name'], $model_array_const); return $checkboxHtml; } protected function getSearchSelectHtml($info) { $name = 'html' . DS . 'search' . DS . 'radio'; $data['field'] = $info['field']; $items = $info['addition']; $options = ''; foreach ($items['value'] as $k => $v) { $options .= "\t\t\t\t\t\t" . '' . "\n"; } $options = "\t\t\t\t" . '' . "\n" . rtrim($options, "\n"); $data['options'] = $options; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } /** * 获取select需要生成的html,在生成add和edit表单的时候可以用到 * @param $info * @param $type string 类型,add或者edit * @return string */ protected function getSelectHtml($info, $type) { $name = 'html' . DS . $type . DS . 'select'; $items = $info['addition']; $options = "\t\t\t\t\t\t\t" . '' . "\n"; foreach ($items['value'] as $k => $v) { if ($type == 'add') { if ($items['value'][$k] === $items['default']) { $options .= "\t\t\t\t\t\t\t" . '' . "\n"; } else { $options .= "\t\t\t\t\t\t\t" . '' . "\n"; } } else { $options .= "\t\t\t\t\t\t\t" . '' . "\n"; } } $data['options'] = $options; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $data['verify'] = $info['is_empty'] == 1 ? '' : 'required'; return $this->getReplacedTpl($name, $data); } protected function getSearchXmSelectHtml($info) { $name = 'html' . DS . 'search' . DS . 'xm_select'; $data['field'] = $info['field']; if ($info['addition']['data_from_type'] === "data") { $data['sourceType'] = "data"; $source = []; foreach ($info['addition']['value'] as $k => $v) { $source[] = ['name' => $info['addition']['text'][$k], 'value' => $info['addition']['value'][$k]]; } // $data['source'] = str_replace('"', '\'', json_encode($source, JSON_UNESCAPED_UNICODE)); $data['source'] = json_encode($source, JSON_UNESCAPED_UNICODE); $data['sourceTree'] = "false"; $data['paging'] = "false"; $data['textField'] = "\n\t\t\t\t\t\t" . 'data-textField=name"'; $data['subTextField'] = ""; $data['iconField'] = ""; $data['valueField'] = "value"; } else { $data['sourceType'] = "route"; $tableName = $info['addition']['table_id']; $midName = str_replace('/', '.', $this->getMidName($tableName)); $data['source'] = $this->compatibleApiRoute($midName) . '/index'; $createType = Table::where('table', '=', $tableName)->value('create_type'); if (!$createType) { $this->setError('生成失败。' . $tableName . '数据表未使用生成程序生成'); return false; } $tableIsTree = ($createType == 1) ? 0 : 1;//取到数据表是否为无限极分类模型 if ($tableIsTree) { $data['sourceTree'] = "true"; $data['paging'] = "false"; } else { $data['sourceTree'] = "false"; $data['paging'] = "true"; } $data['textField'] = $info['addition']['title_field'] ? "\n\t\t\t\t\t\t" . 'data-textField="' . $info['addition']['title_field'] . '"' : ''; $data['subTextField'] = $info['addition']['sub_title_field'] ? "\n\t\t\t\t\t\t" . 'data-subTextField="' . $info['addition']['sub_title_field'] . '"' : ''; $data['iconField'] = $info['addition']['icon_field'] ? "\n\t\t\t\t\t\t" . 'data-iconField="' . $info['addition']['icon_field'] . '"' : ''; $data['valueField'] = "id"; } $data['comment'] = $info['comment'] ? "\n\t\t\t\t\t\t" . 'data-placeholder="请选择' . $info['comment'] . '"' : ''; $data['direction'] = $info['addition']['direction'] ? "\n\t\t\t\t\t\t" . 'data-direction="' . $info['addition']['direction'] . '"' : ''; return $this->getReplacedTpl($name, $data); } protected function getXmSelectHtml($info, $type) { $name = 'html' . DS . $type . DS . 'xm_select'; $data['field'] = $info['field']; if ($info['addition']['data_from_type'] === "data") { $data['sourceType'] = "data"; $source = []; foreach ($info['addition']['value'] as $k => $v) { $source[] = ['name' => $info['addition']['text'][$k], 'value' => $info['addition']['value'][$k]]; } $data['source'] = str_replace('"', '\'', json_encode($source, JSON_UNESCAPED_UNICODE)); $data['sourceTree'] = "false"; $data['paging'] = "false"; $data['textField'] = "\n\t\t\t\t\t\t" . 'data-textField=name"'; $data['subTextField'] = ""; $data['iconField'] = ""; $data['valueField'] = "value"; } else { $data['sourceType'] = "route"; $tableName = $info['addition']['table_id']; $midName = str_replace('/', '.', $this->getMidName($tableName)); $data['source'] = $this->compatibleApiRoute($midName) . '/index'; $createType = Table::where('table', '=', $tableName)->value('create_type'); $tableIsTree = ($createType == 1) ? 0 : 1;//取到数据表是否为无限极分类模型 if ($tableIsTree) { $data['sourceTree'] = "true"; $data['paging'] = "false"; } else { $data['sourceTree'] = "false"; $data['paging'] = "true"; } $data['textField'] = $info['addition']['title_field'] ? "\n\t\t\t\t\t\t\t" . 'data-textField="' . $info['addition']['title_field'] . '"' : ''; $data['subTextField'] = $info['addition']['sub_title_field'] ? "\n\t\t\t\t\t\t\t" . 'data-subTextField="' . $info['addition']['sub_title_field'] . '"' : ''; $data['iconField'] = $info['addition']['icon_field'] ? "\n\t\t\t\t\t\t\t" . 'data-iconField="' . $info['addition']['icon_field'] . '"' : ''; $data['valueField'] = "\n\t\t\t\tdata-valueField=\"id\""; } $data['layVerify'] = ($info['is_empty'] == 1) ? "" : "\n\t\t\t\t\t\t\t" . 'data-layVerify="required"'; $data['comment'] = $info['comment'] ? "\n\t\t\t\t\t\t\t" . 'data-placeholder="请选择' . $info['comment'] . '"' : ''; $data['direction'] = $info['addition']['direction'] ? "\n\t\t\t\t\t\t\t" . 'data-direction="' . $info['addition']['direction'] . '"' : ''; $data['radio'] = ($info['addition']['single_multi_type'] === 'single') ? "true" : "false"; $data['max'] = $info['addition']['max'] ? 'data-max="' . $info['addition']['max'] . '"' : ''; return $this->getReplacedTpl($name, $data); } public function getSearchLinkageSelectHtml($info) { $name = 'html' . DS . 'search' . DS . 'linkage_select'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $midName = str_replace('/', '.', $this->getMidName($info['addition']['table_id'])); $data['url'] = $this->compatibleApiRoute($midName) . '/index'; $data['leftField'] = $info['addition']['left_field']; $data['rightField'] = $info['addition']['right_field']; $data['showField'] = $info['addition']['show_field']; $data['searchField'] = $info['addition']['search_field']; $data['searchCondition'] = $info['addition']['search_condition']; $data['searchVal'] = $info['addition']['search_val']; return $this->getReplacedTpl($name, $data); } public function getLinkageSelectHtml($info, $type) { $name = 'html' . DS . $type . DS . 'linkage_select'; $data['field'] = $info['field']; $data['verify'] = ($info['is_empty'] == 1) ? "" : "required"; $data['comment'] = $info['comment']; $midName = str_replace('/', '.', $this->getMidName($info['addition']['table_id'])); $data['url'] = $this->compatibleApiRoute($midName) . '/index'; $data['leftField'] = $info['addition']['left_field']; $data['rightField'] = $info['addition']['right_field']; $data['showField'] = $info['addition']['show_field']; $data['searchField'] = $info['addition']['search_field']; $data['searchCondition'] = $info['addition']['search_condition']; $data['searchVal'] = $info['addition']['search_val']; return $this->getReplacedTpl($name, $data); } public function getSearchLaydateHtml($info) { $name = 'html' . DS . 'search' . DS . 'laydate'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $data['laydateType'] = $info['addition']['date_type']; if ($info['data_type'] == 'integer') { if (in_array($info['addition']['date_type'], ['datetime', 'month', 'date'])) { $data['searchType'] = 'BETWEEN_STRTOTIME'; } else { $data['searchType'] = 'BETWEEN'; } } else { $data['searchType'] = 'BETWEEN'; } return $this->getReplacedTpl($name, $data); } public function getLaydateHtml($info, $type) { $name = 'html' . DS . $type . DS . 'laydate'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $data['laydateType'] = $info['addition']['date_type']; $data['verify'] = ($info['is_empty'] == 1) ? "" : "required"; return $this->getReplacedTpl($name, $data); } public function getSearchColorPickerHtml() { return ""; } public function getColorPickerHtml($info, $type) { $name = 'html' . DS . $type . DS . 'color_picker'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $data['color'] = $info['addition']['color']; $data['predefine'] = isset($info['addition']['predefine']) ? "true" : "false"; $data['colors'] = isset($info['addition']['colors']) ? json_encode($info['addition']['colors'], JSON_UNESCAPED_UNICODE) : ''; $data['alpha'] = (isset($info['addition']['alpha']) && $info['addition']['alpha']) ? "true" : "false"; $data['format'] = $info['addition']['format']; return $this->getReplacedTpl($name, $data); } public function getSearchUploadHtml() { return ""; } public function getUploadHtml($info, $type) { $name = 'html' . DS . $type . DS . 'upload'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $data['accept'] = $info['addition']['accept']; $data['width'] = ($info['addition']['accept'] == 'image' && $info['addition']['width']) ? "\n\t\t\t\t\t\t\t\tdata-width=\"" . $info['addition']['width'] . "\"" : ""; $data['height'] = ($info['addition']['accept'] == 'image' && $info['addition']['height']) ? "\n\t\t\t\t\t\t\t\tdata-height=\"" . $info['addition']['height'] . "\"" : ""; $data['multi'] = ($info['addition']['multi'] == 'single') ? "false" : "true"; $data['max'] = intval($info['addition']['max']) ? "\n\t\t\t\t\t\t\t\tdata-max=\"" . intval($info['addition']['max']) . "\"" : ""; $data['dir'] = $info['addition']['dir'] ? "\n\t\t\t\t\t\t\t\tdata-dir=\"" . $info['addition']['dir'] . "\"" : ""; $data['url'] = $info['addition']['url'] ? "\n\t\t\t\t\t\t\t\tdata-url=\"" . $info['addition']['url'] . "\"" : ""; $data['mime'] = $info['addition']['mime'] ? "\n\t\t\t\t\t\t\t\tdata-mime=\"" . $info['addition']['mime'] . "\"" : ""; $data['size'] = $info['addition']['size'] ? "\n\t\t\t\t\t\t\t\tdata-size=\"" . $info['addition']['size'] . "\"" : ""; $data['verify'] = ($info['is_empty'] == 1) ? "" : "\n\t\t\t\t\t\t\t\tdata-layVerify=\"required\""; $data['type'] = ($info['addition']['upload_type'] !== "local") ? "\n\t\t\t\t\t\t\tdata-type=\"" . $info['addition']['upload_type'] . "\"" : ""; $data['viaServer'] = ($info['addition']['upload_type'] !== "local" && $info['addition']['via_server'] === "unVia") ? "\n\t\t\t\t\t\t\tdata-viaServer=\"unVia\"" : ""; if ($info['addition']['multi'] == 'single') { $data['uploadedInfo'] = "data-uploaded=\"{{# if(d." . $info['field'] . "_file){ }}{{=d." . $info['field'] . "_file.path}}{{# } }}\" data-uploadedId=\"{{=d." . $info['field'] . "}}\" data-uploadedFilename=\"{{# if(d." . $info['field'] . "_file){ }}{{=d." . $info['field'] . "_file.name}}{{# } }}\""; } else { $data['uploadedInfo'] = "data-uploaded=\"{{=d." . $info['field'] . "_file.path}}\" data-uploadedId=\"{{=d." . $info['field'] . "}}\" data-uploadedFilename=\"{{=d." . $info['field'] . "_file.filename}}\""; } return $this->getReplacedTpl($name, $data); } public function getSearchEditorHtml($info) { $name = 'html' . DS . 'search' . DS . 'editor' . DS . $info['addition']['type']; $data['field'] = $info['field']; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } public function getEditorHtml($info, $type) { $name = 'html' . DS . $type . DS . 'editor' . DS . $info['addition']['type']; $referer = request()->header('referer'); $refDomain = ''; if ($referer) { $refPath = parse_url($referer); $refDomain = $refPath['scheme'] . '://' . $refPath['host']; } $domain = request()->domain(); if ($refDomain && $domain && $refDomain != $domain) { $data['iframeSrc'] = '/' . $info['addition']['type'] . '.html'; } else { $data['iframeSrc'] = '/admin/' . $info['addition']['type'] . '.html'; } if ($info['addition']['upload_type'] != 'local') { if ($type == 'add') { $data['iframeSrc'] .= '?upload_type=' . $info['addition']['upload_type']; } else { $data['iframeSrc'] .= '?id=' . $info['field'] . '&upload_type=' . $info['addition']['upload_type']; } } else { if ($type == 'edit') { $data['iframeSrc'] .= '?id=' . $info['field']; } } $data['field'] = $info['field']; $data['comment'] = $info['comment']; return $this->getReplacedTpl($name, $data); } public function getSearchLinkageXmSelectHtml($info) { $name = 'html' . DS . 'search' . DS . 'linkage_xm_select'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $midName = str_replace('/', '.', $this->getMidName($info['addition']['table_id'])); $data['route'] = $this->compatibleApiRoute($midName) . '/index'; $data['leftId'] = $info['addition']['left_id']; $data['rightId'] = $info['addition']['right_id']; $data['textField'] = $info['addition']['text_field']; $data['subTextField'] = $info['addition']['sub_text_field']; $param = []; foreach ($info['addition']['param']['field'] as $k => $field) { if ($field) { $param[$field] = ['condition' => $info['addition']['param']['condition'][$k], 'value' => $info['addition']['param']['value'][$k]]; } } $data['param'] = $param ? json_encode($param, JSON_UNESCAPED_UNICODE) : ""; $data['paging'] = $info['addition']['paging'] ? "true" : "false"; $data['search'] = $info['addition']['search'] ? "true" : "false"; $searchParam = []; foreach ($info['addition']['search_param']['field'] as $k => $field) { if ($field) { $searchParam[$field] = ['condition' => $info['addition']['search_param']['condition'][$k]]; } } $data['searchParam'] = $searchParam ? json_encode($searchParam, JSON_UNESCAPED_UNICODE) : ""; $leftOnchangeParam = []; foreach ($info['addition']['left_onchange_param']['field'] as $k => $field) { if ($field) { $leftOnchangeParam[$field] = ['condition' => $info['addition']['left_onchange_param']['condition'][$k]]; } } $data['leftOnchangeParam'] = $leftOnchangeParam ? json_encode($leftOnchangeParam, JSON_UNESCAPED_UNICODE) : ""; $data['width'] = (isset($info['addition']['width']) && $info['addition']['width']) ? ' style="width:' . $info['addition']['width'] . 'px"' : ""; return $this->getReplacedTpl($name, $data); } public function getLinkageXmSelectHtml($info, $type) { $name = 'html' . DS . $type . DS . 'linkage_xm_select'; $data['field'] = $info['field']; $data['comment'] = $info['comment']; $data['leftId'] = $info['addition']['left_id']; $data['rightId'] = $info['addition']['right_id']; $midName = str_replace('/', '.', $this->getMidName($info['addition']['table_id'])); $data['route'] = $this->compatibleApiRoute($midName) . '/index'; $data['textField'] = $info['addition']['text_field']; $data['subTextField'] = $info['addition']['sub_text_field']; $param = []; foreach ($info['addition']['param']['field'] as $k => $field) { if ($field) { $param[$field] = ['condition' => $info['addition']['param']['condition'][$k], 'value' => $info['addition']['param']['value'][$k]]; } } $data['param'] = $param ? json_encode($param, JSON_UNESCAPED_UNICODE) : ""; $data['paging'] = $info['addition']['paging'] ? "true" : "false"; $data['search'] = $info['addition']['search'] ? "true" : "false"; $searchParam = []; foreach ($info['addition']['search_param']['field'] as $k => $field) { if ($field) { $searchParam[$field] = ['condition' => $info['addition']['search_param']['condition'][$k]]; } } $data['searchParam'] = $searchParam ? json_encode($searchParam, JSON_UNESCAPED_UNICODE) : ""; $leftOnchangeParam = []; foreach ($info['addition']['left_onchange_param']['field'] as $k => $field) { if ($field) { $leftOnchangeParam[$field] = ['condition' => $info['addition']['search_param']['condition'][$k]]; } } $data['leftOnchangeParam'] = $leftOnchangeParam ? json_encode($leftOnchangeParam, JSON_UNESCAPED_UNICODE) : ""; $data['verify'] = ($info['is_empty'] == 1) ? "" : "required"; $data['width'] = (isset($info['addition']['width']) && $info['addition']['width']) ? ' style="width:' . $info['addition']['width'] . 'px"' : ""; return $this->getReplacedTpl($name, $data); } /** * 设置生成验证器需要的参数 * [ * 'tplName'=>模板名, * 'data' => '执行替换模板的key=>value数组', * 'fileName' => '要生成的文件名' * ] */ protected function setValidateParam() { $addRule = []; $editRule = []; $addMessage = []; $editMessage = []; foreach ($this->fields as $field) { if ($field['form_type'] == 'password') { $addFieldRule = []; $editFieldRule = []; if ($field['is_empty'] == 2) { $addFieldRule[] = 'require'; $addMessage[] = '\'' . $field['field'] . '.require\' => \'' . $field['comment'] . '不能为空\','; $editFieldRule[] = 'require'; $editMessage[] = '\'' . $field['field'] . '.require\' => \'' . $field['comment'] . '不能为空\','; } if ($field['addition']['re_password'] == 1) { $addFieldRule[] = "confirm:re_" . $field['field']; $addMessage[] = '\'' . $field['field'] . '.confirm\' => \'两次' . $field['comment'] . '输入不相同\','; $editFieldRule[] = "confirm:re_" . $field['field']; $editMessage[] = '\'' . $field['field'] . '.confirm\' => \'两次' . $field['comment'] . '输入不相同\','; } if ($field['addition']['password_min_length']) { $addFieldRule[] = "min:" . $field['addition']['password_min_length']; $addMessage[] = '\'' . $field['field'] . '.min\' => \'' . $field['comment'] . '长度不能低于' . $field['addition']['password_min_length'] . '个字符\','; $editFieldRule[] = "min:" . $field['addition']['password_min_length']; $editMessage[] = '\'' . $field['field'] . '.min\' => \'' . $field['comment'] . '长度不能低于' . $field['addition']['password_min_length'] . '个字符\','; } if ($field['addition']['password_max_length']) { $addFieldRule[] = "max:" . $field['addition']['password_max_length']; $addMessage[] = '\'' . $field['field'] . '.max\' => \'' . $field['comment'] . '长度不能高于' . $field['addition']['password_max_length'] . '个字符\','; $editFieldRule[] = "max:" . $field['addition']['password_max_length']; $editMessage[] = '\'' . $field['field'] . '.max\' => \'' . $field['comment'] . '长度不能高于' . $field['addition']['password_max_length'] . '个字符\','; } $addFieldRule && $addRule[] = '\'' . $field['field'] . '\' => \'' . implode('|', $addFieldRule) . '\','; $editFieldRule && $editRule[] = '\'' . $field['field'] . '\' => \'' . implode('|', $editFieldRule) . '\','; } } $addTplName = 'validate' . DS . 'add'; $addData = []; $addData['validateNamespace'] = str_replace('/', '\\', 'app/validate/admin/' . $this->filterMidName(strtolower($this->midName))); $addData['rule'] = implode(',', $addRule); $addData['message'] = implode("\r\n\t\t", $addMessage); $this->validateAddParam = ['tplName' => $addTplName, 'data' => $addData, 'fileName' => $this->validateAddFileName]; $editTplName = 'validate' . DS . 'edit'; $editData = []; $editData['validateNamespace'] = str_replace('/', '\\', 'app/validate/admin/' . $this->filterMidName(strtolower($this->midName))); $editData['rule'] = implode(',', $editRule); $editData['message'] = implode("\r\n\t\t", $editMessage); $this->validateEditParam = ['tplName' => $editTplName, 'data' => $editData, 'fileName' => $this->validateEditFileName]; } // 生成验证器 protected function createValidate() { $this->writeToFile($this->validateAddParam['tplName'], $this->validateAddParam['data'], $this->validateAddParam['fileName']); $this->writeToFile($this->validateEditParam['tplName'], $this->validateEditParam['data'], $this->validateEditParam['fileName']); } /** * 写入到文件 * @param string $name 模板文件名 * @param array $data key=>value形式的替换数组 * @param string $pathname 生成的绝对文件名 * @return mixed */ protected function writeToFile($name, $data, $pathname) { foreach ($data as $index => &$datum) { $datum = is_array($datum) ? '' : $datum; } unset($datum); $content = $this->getReplacedTpl($name, $data); if (!is_dir(dirname($pathname))) { mkdir(dirname($pathname), 0777, true); } return file_put_contents($pathname, $content); } /** * 获取替换后的数据 * @param string $name 模板文件名 * @param array $data key=>value形式的替换数组 * @return string */ protected function getReplacedTpl($name, $data = []) { foreach ($data as $index => &$datum) { $datum = is_array($datum) ? '' : $datum; } unset($datum); $search = $replace = []; foreach ($data as $k => $v) { $search[] = "{%{$k}%}"; $replace[] = $v; } $tplTrueName = $this->getTplTrueName($name); $tpl = file_get_contents($tplTrueName); $content = str_replace($search, $replace, $tpl); return $content; } /** * 获取模板文件真实路径 * @param string $name 举例: $name = 'controller' . DS . 'edit'; * @return string */ protected function getTplTrueName($name) { return app()->getRootPath() . DS . 'plugin' . DS . 'curd' . DS . 'library' . DS . 'curd_template' . DS . $name . '.lt'; } /** * 下划线转驼峰 * @param $str * @return string|string[]|null */ protected function underlineToCamel($str) { $str = preg_replace_callback('/([-_]+([a-z]{1}))/i', function ($matches) { return strtoupper($matches[2]); }, $str); return $str; } }