| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575 |
- <?php
- namespace app\admin\service\curd;
- use app\admin\service\curd\exceptions\TableException;
- use app\admin\service\tool\CommonTool;
- use Exception;
- use think\exception\FileException;
- use think\facade\Db;
- /**
- * 快速构建系统CURD
- * Class BuildCurd
- * @package EasyAdmin\curd
- */
- class BuildCurd
- {
- /**
- * 当前目录
- * @var string
- */
- protected string $dir;
- /**
- * 应用目录
- * @var string
- */
- protected string $rootDir;
- /**
- * 分隔符
- * @var string
- */
- protected string $DS = DIRECTORY_SEPARATOR;
- /**
- * 数据库名
- * @var string
- */
- protected mixed $dbName;
- /**
- * 表前缀
- * @var string
- */
- protected mixed $tablePrefix = 'ea';
- /**
- * 主表
- * @var string
- */
- protected string $table;
- /**
- * 表注释名
- * @var string
- */
- protected string $tableComment;
- /**
- * 主表列信息
- * @var array
- */
- protected array $tableColumns;
- /**
- * 数据列表可见字段
- * @var string
- */
- protected string $fields;
- /**
- * 是否软删除模式
- * @var bool
- */
- protected bool $delete = false;
- /**
- * 是否强制覆盖
- * @var bool
- */
- protected bool $force = false;
- /**
- * 关联模型
- * @var array
- */
- protected array $relationArray = [];
- /**
- * 控制器对应的URL
- * @var string
- */
- protected string $controllerUrl;
- /**
- * 生成的控制器名
- * @var string
- */
- protected string $controllerFilename;
- /**
- * 控制器命名
- * @var string
- */
- protected string $controllerName;
- /**
- * 控制器命名空间
- * @var string
- */
- protected string $controllerNamespace;
- /**
- * 视图名
- * @var string
- */
- protected string $viewFilename;
- /**
- * js文件名
- * @var string
- */
- protected string $jsFilename;
- /**
- * 生成的模型文件名
- * @var string
- */
- protected string $modelFilename;
- /**
- * 主表模型命名
- * @var string
- */
- protected string $modelName;
- /**
- * 复选框字段后缀
- * @var array
- */
- protected array $checkboxFieldSuffix = ['checkbox'];
- /**
- * 单选框字段后缀
- * @var array
- */
- protected array $radioFieldSuffix = ['radio'];
- /**
- * 下拉字段后缀
- * @var array
- */
- protected array $selectFieldSuffix = ['select'];
- /**
- * 单图片字段后缀
- * @var array
- */
- protected array $imageFieldSuffix = ['image', 'logo', 'photo', 'icon'];
- /**
- * 多图片字段后缀
- * @var array
- */
- protected array $imagesFieldSuffix = ['images', 'photos', 'icons'];
- /**
- * 单文件字段后缀
- * @var array
- */
- protected array $fileFieldSuffix = ['file'];
- /**
- * 多文件字段后缀
- * @var array
- */
- protected array $filesFieldSuffix = ['files'];
- /**
- * 日期字段后缀
- * @var array
- */
- protected array $dateFieldSuffix = ['date', 'time'];
- /**
- * 日期时间字段后缀
- * @var array
- */
- protected array $datetimeFieldSuffix = ['datetime'];
- /**
- * 开关组件字段
- * @var array
- */
- protected array $switchFields = [];
- /**
- * 下拉选择字段
- * @var array
- */
- protected array $selectFields = ['select'];
- /**
- * 单选字段
- * @var array
- */
- protected array $radioFields = ['radio'];
- /**
- * 复选字段
- * @var array
- */
- protected array $checkboxFields = ['checkbox'];
- /**
- * 富文本字段
- * @var array
- */
- protected array $editorFields = [];
- /**
- * 排序字段
- * @var array
- */
- protected array $sortFields = [];
- /**
- * 忽略字段
- * @var array
- */
- protected array $ignoreFields = ['update_time', 'delete_time'];
- /**
- * 外键字段
- * @var array
- */
- protected array $foreignKeyFields = [];
- /**
- * 相关生成文件
- * @var array
- */
- protected array $fileList = [];
- /**
- * 表单类型
- * @var array
- */
- protected array $formTypeArray = ['text', 'image', 'images', 'file', 'files', 'select', 'switch', 'date', 'editor', 'textarea', 'checkbox', 'radio'];
- /**
- * 初始化
- * BuildCurd constructor.
- */
- public function __construct()
- {
- $this->tablePrefix = config('database.connections.mysql.prefix');
- $this->dbName = config('database.connections.mysql.database');
- $this->dir = __DIR__;
- $this->rootDir = root_path();
- return $this;
- }
- public function setTablePrefix($prefix): static
- {
- $this->tablePrefix = $prefix;
- return $this;
- }
- /**
- * 设置主表
- * @param $table
- * @return $this
- * @throws TableException
- */
- public function setTable($table): static
- {
- $this->table = $table;
- try {
- // 获取表列注释
- $columns = Db::query("SHOW FULL COLUMNS FROM {$this->tablePrefix}{$this->table}");
- foreach ($columns as $vo) {
- $colum = [
- 'type' => $vo['Type'],
- 'comment' => !empty($vo['Comment']) ? $vo['Comment'] : $vo['Field'],
- 'required' => $vo['Null'] == "NO",
- 'default' => $vo['Default'],
- ];
- // 格式化列数据
- $this->buildColum($colum);
- $this->tableColumns[$vo['Field']] = $colum;
- if ($vo['Field'] == 'delete_time') {
- $this->delete = true;
- }
- }
- $this->tableComment = $this->table;
- } catch (Exception $e) {
- throw new TableException($e->getMessage());
- }
- // 初始化默认控制器名
- $nodeArray = explode('_', $this->table);
- if (count($nodeArray) == 1) {
- $this->controllerFilename = ucfirst($nodeArray[0]);
- } else {
- foreach ($nodeArray as $k => $v) {
- if ($k == 0) {
- $this->controllerFilename = "{$v}{$this->DS}";
- } else {
- $this->controllerFilename .= ucfirst($v);
- }
- }
- }
- // 初始化默认模型名
- $this->modelFilename = ucfirst(CommonTool::lineToHump($this->table));
- $this->buildViewJsUrl();
- // 构建数据
- $this->buildStructure();
- return $this;
- }
- /**
- * 设置关联表
- * @param $relationTable
- * @param $foreignKey
- * @param null $primaryKey
- * @param null $modelFilename
- * @param array $onlyShowFields
- * @param null $bindSelectField
- * @return $this
- * @throws TableException
- */
- public function setRelation($relationTable, $foreignKey, $primaryKey = null, $modelFilename = null, array $onlyShowFields = [], $bindSelectField = null): static
- {
- if (!isset($this->tableColumns[$foreignKey])) {
- throw new TableException("主表不存在外键字段:{$foreignKey}");
- }
- if (!empty($modelFilename)) {
- $modelFilename = str_replace('/', $this->DS, $modelFilename);
- }
- try {
- $columns = Db::query("SHOW FULL COLUMNS FROM {$this->tablePrefix}{$relationTable}");
- $formatColumns = [];
- $delete = false;
- if (!empty($bindSelectField) && !in_array($bindSelectField, array_column($columns, 'Field'))) {
- throw new TableException("关联表{$relationTable}不存在该字段: {$bindSelectField}");
- }
- $onlyFields = [];
- foreach ($columns as $vo) {
- if (empty($primaryKey) && $vo['Key'] == 'PRI') {
- $primaryKey = $vo['Field'];
- }
- if (!empty($onlyShowFields) && !in_array($vo['Field'], $onlyShowFields)) {
- continue;
- }
- if (!empty($onlyShowFields)) $onlyFields[] = $vo['Field'];
- $colum = [
- 'type' => $vo['Type'],
- 'comment' => $vo['Comment'],
- 'default' => $vo['Default'],
- ];
- $this->buildColum($colum);
- $formatColumns[$vo['Field']] = $colum;
- if ($vo['Field'] == 'delete_time') {
- $delete = true;
- }
- }
- $modelFilename = empty($modelFilename) ? ucfirst(CommonTool::lineToHump($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' => $formatColumns,
- 'onlyFields' => $onlyFields,
- ];
- if (!empty($bindSelectField)) {
- $relationArray = explode('\\', $modelFilename);
- $this->tableColumns[$foreignKey]['bindSelectField'] = $bindSelectField;
- $this->tableColumns[$foreignKey]['bindRelation'] = lcfirst(end($relationArray)) . ucfirst($bindSelectField);
- }
- $this->relationArray[$relationTable] = $relation;
- $this->selectFields[] = $foreignKey;
- } catch (Exception $e) {
- throw new TableException($e->getMessage());
- }
- return $this;
- }
- /**
- * 设置控制器名
- * @param $controllerFilename
- * @return $this
- */
- public function setControllerFilename($controllerFilename): static
- {
- $this->controllerFilename = str_replace('/', $this->DS, $controllerFilename);
- $this->buildViewJsUrl();
- return $this;
- }
- /**
- * 设置模型名
- * @param $modelFilename
- * @return $this
- */
- public function setModelFilename($modelFilename): static
- {
- $this->modelFilename = str_replace('/', $this->DS, $modelFilename);
- $this->buildViewJsUrl();
- return $this;
- }
- /**
- * 设置显示字段
- * @param $fields
- * @return $this
- */
- public function setFields($fields): static
- {
- $this->fields = $fields;
- return $this;
- }
- /**
- * 设置删除模式
- * @param $delete
- * @return $this
- */
- public function setDelete($delete): static
- {
- $this->delete = $delete;
- return $this;
- }
- /**
- * 设置是否强制替换
- * @param $force
- * @return $this
- */
- public function setForce($force): static
- {
- $this->force = $force;
- return $this;
- }
- /**
- * 设置复选框字段后缀
- * @param $array
- * @return $this
- */
- public function setCheckboxFieldSuffix($array, $replace = false): static
- {
- $this->checkboxFieldSuffix = $replace ? $array : array_merge($this->checkboxFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置单选框字段后缀
- * @param $array
- * @return $this
- */
- public function setRadioFieldSuffix($array, $replace = false): static
- {
- $this->radioFieldSuffix = $replace ? $array : array_merge($this->radioFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置单图片字段后缀
- * @param $array
- * @return $this
- */
- public function setImageFieldSuffix($array, $replace = false): static
- {
- $this->imageFieldSuffix = $replace ? $array : array_merge($this->imageFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置多图片字段后缀
- * @param $array
- * @return $this
- */
- public function setImagesFieldSuffix($array, $replace = false): static
- {
- $this->imagesFieldSuffix = $replace ? $array : array_merge($this->imagesFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置单文件字段后缀
- * @param $array
- * @return $this
- */
- public function setFileFieldSuffix($array, $replace = false): static
- {
- $this->fileFieldSuffix = $replace ? $array : array_merge($this->fileFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置多文件字段后缀
- * @param $array
- * @return $this
- */
- public function setFilesFieldSuffix($array, $replace = false): static
- {
- $this->filesFieldSuffix = $replace ? $array : array_merge($this->filesFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置日期字段后缀
- * @param $array
- * @return $this
- */
- public function setDateFieldSuffix($array, $replace = false): static
- {
- $this->dateFieldSuffix = $replace ? $array : array_merge($this->dateFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置日期时间字段后缀
- * @param $array
- * @return $this
- */
- public function setDatetimeFieldSuffix($array, $replace = false): static
- {
- $this->datetimeFieldSuffix = $replace ? $array : array_merge($this->datetimeFieldSuffix, $array);
- return $this;
- }
- /**
- * 设置开关字段
- * @param $array
- * @return $this
- */
- public function setSwitchFields($array, $replace = false): static
- {
- $this->switchFields = $replace ? $array : array_merge($this->switchFields, $array);
- return $this;
- }
- /**
- * 设置下拉选择字段
- * @param $array
- * @return $this
- */
- public function setSelectFields($array, $replace = false): static
- {
- $this->selectFields = $replace ? $array : array_merge($this->selectFields, $array);
- return $this;
- }
- /**
- * 设置排序字段
- * @param $array
- * @return $this
- */
- public function setSortFields($array, $replace = false): static
- {
- $this->sortFields = $replace ? $array : array_merge($this->sortFields, $array);
- return $this;
- }
- /**
- * 设置忽略字段
- * @param $array
- * @return $this
- */
- public function setIgnoreFields($array, $replace = false): static
- {
- $this->ignoreFields = $replace ? $array : array_merge($this->ignoreFields, $array);
- return $this;
- }
- public function setEditorFields($array, $replace = false): static
- {
- $this->editorFields = $replace ? $array : array_merge($this->editorFields, $array);
- return $this;
- }
- /**
- * 获取相关的文件
- * @return array
- */
- public function getFileList(): array
- {
- return $this->fileList;
- }
- /**
- * 构建基础视图、JS、URL
- * @return $this
- */
- protected function buildViewJsUrl(): static
- {
- $nodeArray = explode($this->DS, $this->controllerFilename);
- $formatArray = [];
- foreach ($nodeArray as $vo) {
- $formatArray[] = CommonTool::humpToLine(lcfirst($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}";
- // 主表模型命名
- $modelArray = explode($this->DS, $this->modelFilename);
- $this->modelName = array_pop($modelArray);
- return $this;
- }
- /**
- * 构建字段
- * @return $this
- */
- protected function buildStructure(): static
- {
- foreach ($this->tableColumns as $key => $val) {
- // 排序
- if ($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): string
- {
- return $require ? 'lay-verify="required"' : "";
- }
- /**
- * 构建初始化字段信息
- * @param $colum
- * @return array
- */
- protected function buildColum(&$colum): array
- {
- $string = $colum['comment'];
- $colum['define'] = json_encode([1 => '系统自动生成A', 2 => '请自行修改B'], JSON_UNESCAPED_UNICODE);
- // 处理定义类型
- preg_match('/{[\s\S]*?}/i', $string, $formTypeMatch);
- if (!empty($formTypeMatch) && isset($formTypeMatch[0])) {
- $colum['comment'] = str_replace($formTypeMatch[0], '', $colum['comment']);
- $formType = trim(str_replace('}', '', str_replace('{', '', $formTypeMatch[0])));
- $_formType = $this->checkCommentFormType($formType);
- if ($_formType) {
- $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'])) {
- $define = str_replace(')', '', str_replace('(', '', $defineMatch[0]));
- if (in_array($colum['formType'], ['select', 'switch', 'radio', 'checkbox'])) {
- $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']);
- return $colum;
- }
- /**
- * 构建下拉控制器
- * @param $field
- * @return mixed
- */
- protected function buildSelectController($field): mixed
- {
- $field = CommonTool::lineToHump(ucfirst($field));
- $name = "get{$field}List";
- $selectCode = CommonTool::replaceTemplate(
- $this->getTemplate("controller{$this->DS}select"),
- [
- 'name' => $name,
- ]
- );
- return $selectCode;
- }
- /**
- * 构架下拉模型
- * @param $field
- * @param $array
- * @return mixed
- */
- protected function buildSelectModel($field, $array): mixed
- {
- $field = CommonTool::lineToHump(ucfirst($field));
- $name = "get{$field}List";
- $values = '[';
- foreach ($array as $k => $v) {
- $values .= "'{$k}'=>'{$v}',";
- }
- $values .= ']';
- $selectCode = CommonTool::replaceTemplate(
- $this->getTemplate("model{$this->DS}select"),
- [
- 'name' => $name,
- 'values' => $values,
- ]
- );
- return $selectCode;
- }
- /**
- * 构架关联下拉模型
- * @param $relation
- * @param $filed
- * @return mixed
- */
- protected function buildRelationSelectModel($relation, $field): mixed
- {
- $relationArray = explode('\\', $relation);
- $name = end($relationArray);
- $name = "get{$name}List";
- $selectCode = CommonTool::replaceTemplate(
- $this->getTemplate("model{$this->DS}relationSelect"),
- [
- 'name' => "notes['$field']",
- 'relation' => $relation,
- 'values' => $field,
- ]
- );
- return $selectCode;
- }
- /**
- * 构建下拉框视图
- * @param $field
- * @param string $select
- * @return mixed
- */
- protected function buildOptionView($field, string $select = '')
- {
- // $field = CommonTool::lineToHump(ucfirst($field));
- // $name = "get{$field}List";
- return CommonTool::replaceTemplate(
- $this->getTemplate("view{$this->DS}module{$this->DS}option"),
- [
- 'name' => "notes['$field']",
- 'select' => $select,
- ]
- );
- }
- /**
- * 构建单选框视图
- * @param $field
- * @param string $select
- * @return mixed
- */
- protected function buildRadioView($field, string $select = ''): mixed
- {
- // $formatField = CommonTool::lineToHump(ucfirst($field));
- // $name = "get{$formatField}List";
- return CommonTool::replaceTemplate(
- $this->getTemplate("view{$this->DS}module{$this->DS}radioInput"),
- [
- 'field' => $field,
- 'name' => "notes['$field']",
- 'select' => $select,
- ]
- );
- }
- /**
- * 构建多选框视图
- * @param $field
- * @param string $select
- * @return mixed
- */
- protected function buildCheckboxView($field, string $select = ''): mixed
- {
- // $formatField = CommonTool::lineToHump(ucfirst($field));
- // $name = "get{$formatField}List";
- return CommonTool::replaceTemplate(
- $this->getTemplate("view{$this->DS}module{$this->DS}checkboxInput"),
- [
- 'field' => $field,
- 'name' => "notes['$field']",
- 'select' => $select,
- ]
- );
- }
- /**
- * 初始化
- * @return $this
- */
- public function render(): static
- {
- // 初始化数据
- $this->renderData();
- // 控制器
- $this->renderController();
- // 模型
- $this->renderModel();
- // 视图
- $this->renderView();
- // JS
- $this->renderJs();
- return $this;
- }
- /**
- * 初始化数据
- * @return $this
- */
- protected function renderData(): static
- {
- // 主表
- foreach ($this->tableColumns as $field => $val) {
- // 过滤字段
- if (in_array($field, $this->ignoreFields)) {
- unset($this->tableColumns[$field]);
- continue;
- }
- $this->tableColumns[$field]['formType'] = $this->tableColumns[$field]['formType'] ?? 'text';
- // 判断图片
- 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 ($this->checkContain($field, $this->datetimeFieldSuffix)) {
- $this->tableColumns[$field]['formType'] = 'datetime';
- continue;
- }
- if (in_array($field, $this->radioFields) || $this->checkContain($field, $this->radioFieldSuffix)) {
- $this->tableColumns[$field]['formType'] = 'radio';
- continue;
- }
- if (in_array($field, $this->checkboxFields) || $this->checkContain($field, $this->checkboxFieldSuffix)) {
- $this->tableColumns[$field]['formType'] = 'checkbox';
- continue;
- }
- // 判断开关
- if (in_array($field, $this->switchFields)) {
- $this->tableColumns[$field]['formType'] = 'switch';
- continue;
- }
- // 判断富文本
- if (in_array($field, $this->editorFields) || in_array($val['type'], ['text', 'tinytext', 'mediumtext', 'longtext'])) {
- $this->tableColumns[$field]['formType'] = 'editor';
- continue;
- }
- // 判断排序
- if (in_array($field, $this->sortFields)) {
- $this->tableColumns[$field]['formType'] = 'sort';
- continue;
- }
- // 判断下拉选择
- if (in_array($field, $this->selectFields)) {
- $this->tableColumns[$field]['formType'] = 'select';
- continue;
- }
- }
- // 关联表
- 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) || in_array($val['type'], ['text', 'tinytext', 'mediumtext', 'longtext'])) {
- $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->selectFields)) {
- $this->relationArray[$table]['tableColumns'][$field]['formType'] = 'select';
- continue;
- }
- $this->relationArray[$table]['tableColumns'][$field]['formType'] = 'text';
- }
- }
- return $this;
- }
- /**
- * 初始化控制器
- * @return $this
- */
- protected function renderController(): static
- {
- $controllerFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}controller{$this->DS}{$this->controllerFilename}.php";
- $constructRelation = '';
- if (empty($this->relationArray)) {
- $controllerIndexMethod = '';
- } else {
- $relationCode = '';
- foreach ($this->relationArray as $key => $val) {
- $relation = CommonTool::lineToHump($key);
- $relationCode = "withJoin('{$relation}', 'LEFT')";
- if (!empty($val['bindSelectField']) && !empty($val['primaryKey'])) {
- $constructRelation = '$notes["' . lcfirst($val['foreignKey']) . '"] = \app\admin\model\\' . $val['modelFilename'] . '::column("' . $val['bindSelectField'] . '", "' . $val['primaryKey'] . '");';
- }
- }
- $controllerIndexMethod = CommonTool::replaceTemplate(
- $this->getTemplate("controller{$this->DS}indexMethod"),
- [
- 'relationIndexMethod' => $relationCode,
- ]
- );
- }
- $selectList = '';
- // foreach ($this->relationArray as $relation) {
- // if (!empty($relation['bindSelectField'])) {
- // $relationArray = explode('\\', $relation['modelFilename']);
- // $selectList .= $this->buildSelectController(end($relationArray));
- // }
- // }
- // foreach ($this->tableColumns as $field => $val) {
- // if (isset($val['formType']) && in_array($val['formType'], ['select', 'switch', 'radio', 'checkbox']) && isset($val['define'])) {
- // $selectList .= $this->buildSelectController($field);
- // }
- // }
- $modelFilenameExtend = str_replace($this->DS, '\\', $this->modelFilename);
- $controllerValue = CommonTool::replaceTemplate(
- $this->getTemplate("controller{$this->DS}controller"),
- [
- 'controllerName' => $this->controllerName,
- 'controllerNamespace' => $this->controllerNamespace,
- 'controllerAnnotation' => $this->tableComment,
- 'modelFilename' => "\app\admin\model\\{$modelFilenameExtend}",
- 'indexMethod' => $controllerIndexMethod,
- 'selectList' => $selectList,
- 'constructRelation' => $constructRelation,
- ]
- );
- $this->fileList[$controllerFile] = $controllerValue;
- return $this;
- }
- /**
- * 初始化模型
- * @return $this
- */
- protected function renderModel(): static
- {
- // 主表模型
- $modelFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}model{$this->DS}{$this->modelFilename}.php";
- $relationList = '';
- if (!empty($this->relationArray)) {
- foreach ($this->relationArray as $key => $val) {
- $relation = CommonTool::lineToHump($key);
- $relationCode = CommonTool::replaceTemplate(
- $this->getTemplate("model{$this->DS}relation"),
- [
- 'relationMethod' => $relation,
- 'relationModel' => "{$val['modelFilename']}::class",
- 'foreignKey' => $val['foreignKey'],
- 'primaryKey' => $val['primaryKey'],
- 'relationFields' => empty($val['onlyFields']) ? "" : "->field('{$val['primaryKey']}," . implode(',', $val['onlyFields']) . "')",
- ]);
- $relationList .= $relationCode;
- }
- }
- $selectList = '';
- foreach ($this->relationArray as $relation) {
- if (!empty($relation['bindSelectField'])) {
- $selectList .= $this->buildRelationSelectModel($relation['modelFilename'], $relation['bindSelectField']);
- }
- }
- $selectArrays = [];
- foreach ($this->tableColumns as $field => $val) {
- if (isset($val['formType']) && in_array($val['formType'], ['select', 'switch', 'radio', 'checkbox']) && isset($val['define'])) {
- $selectArrays += [$field => is_array($val['define']) ? $val['define'] : json_decode($val['define'], true)];
- }
- }
- $extendNamespaceArray = explode($this->DS, $this->modelFilename);
- $extendNamespace = null;
- if (count($extendNamespaceArray) > 1) {
- array_pop($extendNamespaceArray);
- $extendNamespace = '\\' . implode('\\', $extendNamespaceArray);
- }
- $modelValue = CommonTool::replaceTemplate(
- $this->getTemplate("model{$this->DS}model"),
- [
- 'modelName' => $this->modelName,
- 'modelNamespace' => "app\admin\model{$extendNamespace}",
- 'prefix_table' => $this->tablePrefix == config('database.connections.mysql.prefix') ? "" : $this->tablePrefix . $this->table,
- 'table' => $this->table,
- 'deleteTime' => $this->delete ? '"delete_time"' : 'false',
- 'relationList' => $relationList,
- // 'selectList' => $selectList,
- 'selectArrays' => CommonTool::replaceArrayString(var_export($selectArrays, true)),
- ]
- );
- $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 (CommonTool::humpToLine(lcfirst($tableName)) == CommonTool::humpToLine(lcfirst($key))) {
- continue;
- }
- }
- $extendNamespaceArray = explode($this->DS, $val['modelFilename']);
- $extendNamespace = null;
- if (count($extendNamespaceArray) > 1) {
- array_pop($extendNamespaceArray);
- $extendNamespace = '\\' . implode('\\', $extendNamespaceArray);
- }
- $relationModelValue = CommonTool::replaceTemplate(
- $this->getTemplate("model{$this->DS}model"),
- [
- 'modelName' => $val['modelName'],
- 'modelNamespace' => "app\admin\model{$extendNamespace}",
- 'prefix_table' => $this->tablePrefix == config('database.connections.mysql.prefix') ? "" : $this->tablePrefix . $this->table,
- 'table' => $key,
- 'deleteTime' => $val['delete'] ? '"delete_time"' : 'false',
- 'relationList' => '',
- 'selectList' => '',
- 'selectArrays' => "[]",
- ]
- );
- $this->fileList[$relationModelFile] = $relationModelValue;
- }
- return $this;
- }
- /**
- * 初始化视图
- * @return $this
- */
- protected function renderView(): static
- {
- // 列表页面
- $viewIndexFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}index.html";
- $viewIndexValue = CommonTool::replaceTemplate(
- $this->getTemplate("view{$this->DS}index"),
- [
- 'controllerUrl' => $this->controllerUrl,
- 'notesScript' => $this->formatNotesScript(),
- ]
- );
- $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;
- }
- $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 = $val['define'] ?? '|';
- if (strlen($define) > 5) $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 = $val['define'] ?? '|';
- } elseif ($val['formType'] == 'editor') {
- $templateFile = "view{$this->DS}module{$this->DS}editor";
- $val['default'] = '""';
- } elseif ($val['formType'] == 'date') {
- $templateFile = "view{$this->DS}module{$this->DS}date";
- $define = 'date';
- } elseif ($val['formType'] == 'datetime') {
- $templateFile = "view{$this->DS}module{$this->DS}date";
- $define = 'datetime';
- } elseif ($val['formType'] == 'radio') {
- $templateFile = "view{$this->DS}module{$this->DS}radio";
- if (!empty($val['define'])) {
- $define = $this->buildRadioView($field, '');
- }
- } elseif ($val['formType'] == 'checkbox') {
- $templateFile = "view{$this->DS}module{$this->DS}checkbox";
- if (!empty($val['define'])) {
- $define = $this->buildCheckboxView($field, '');
- }
- } elseif ($val['formType'] == 'select') {
- $templateFile = "view{$this->DS}module{$this->DS}select";
- if (isset($val['bindRelation'])) {
- $define = $this->buildOptionView($field);
- } elseif (!empty($val['define'])) {
- $define = $this->buildOptionView($field);
- }
- } elseif ($field == 'remark' || $val['formType'] == 'textarea') {
- $templateFile = "view{$this->DS}module{$this->DS}textarea";
- } elseif ($field == 'sort') {
- $templateFile = "view{$this->DS}module{$this->DS}sort";
- }
- $addFormList .= CommonTool::replaceTemplate(
- $this->getTemplate($templateFile),
- [
- 'comment' => $val['comment'],
- 'field' => $field,
- 'required' => $this->buildRequiredHtml($val['required']),
- 'value' => $val['default'],
- 'define' => $define,
- ]
- );
- }
- $viewAddValue = CommonTool::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 . '"]';
- } elseif ($val['formType'] == 'date') {
- $templateFile = "view{$this->DS}module{$this->DS}date";
- $define = 'date';
- } elseif ($val['formType'] == 'datetime') {
- $templateFile = "view{$this->DS}module{$this->DS}date";
- $define = 'datetime';
- } elseif ($val['formType'] == 'radio') {
- $templateFile = "view{$this->DS}module{$this->DS}radio";
- if (!empty($val['define'])) {
- $define = $this->buildRadioView($field, '{if $row.' . $field . '==$k}checked{/if}');
- }
- } elseif ($val['formType'] == 'checkbox') {
- $templateFile = "view{$this->DS}module{$this->DS}checkbox";
- if (!empty($val['define'])) {
- $define = $this->buildCheckboxView($field, '{if $row.' . $field . '==$k}checked{/if}');
- }
- } elseif ($val['formType'] == 'select') {
- $templateFile = "view{$this->DS}module{$this->DS}select";
- if (isset($val['bindRelation'])) {
- $define = $this->buildOptionView($field, '{if $row.' . $field . '==$k}selected{/if}');
- } elseif (!empty($val['define'])) {
- $define = $this->buildOptionView($field, '{if $row.' . $field . '==$k}selected{/if}');
- }
- } elseif ($field == 'remark' || $val['formType'] == 'textarea') {
- $templateFile = "view{$this->DS}module{$this->DS}textarea";
- $value = '{$row.' . $field . '|raw|default=\'\'}';
- } elseif ($field == 'sort') {
- $templateFile = "view{$this->DS}module{$this->DS}sort";
- }
- $editFormList .= CommonTool::replaceTemplate(
- $this->getTemplate($templateFile),
- [
- 'comment' => $val['comment'],
- 'field' => $field,
- 'required' => $this->buildRequiredHtml($val['required']),
- 'value' => $value,
- 'define' => $define,
- ]
- );
- }
- $viewEditValue = CommonTool::replaceTemplate(
- $this->getTemplate("view{$this->DS}form"),
- [
- 'formList' => $editFormList,
- ]
- );
- $this->fileList[$viewEditFile] = $viewEditValue;
- $viewRecycleFile = "{$this->rootDir}app{$this->DS}admin{$this->DS}view{$this->DS}{$this->viewFilename}{$this->DS}recycle.html";
- $viewRecycleValue = CommonTool::replaceTemplate(
- $this->getTemplate("view{$this->DS}recycle"),
- [
- 'controllerUrl' => $this->controllerUrl,
- 'notesScript' => $this->formatNotesScript(),
- ]
- );
- $this->fileList[$viewRecycleFile] = $viewRecycleValue;
- return $this;
- }
- /**
- * 初始化JS
- * @return $this
- */
- protected function renderJs(): static
- {
- $jsFile = "{$this->rootDir}public{$this->DS}static{$this->DS}admin{$this->DS}js{$this->DS}{$this->jsFilename}.js";
- $indexCols = " {type: 'checkbox'},\r";
- // 主表字段
- foreach ($this->tableColumns as $field => $val) {
- if ($val['formType'] == 'image') {
- $templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.image}";
- } elseif ($val['formType'] == 'datetime') {
- $templateValue = "{field: '{$field}', search: 'range', title: '{$val['comment']}'}";
- } elseif ($val['formType'] == 'images') {
- continue;
- } elseif ($val['formType'] == 'file') {
- $templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.url}";
- } elseif ($val['formType'] == 'files') {
- continue;
- } elseif ($val['formType'] == 'editor') {
- continue;
- } elseif (in_array($field, $this->switchFields)) {
- if (!empty($val['define'])) {
- $templateValue = "{field: '{$field}', search: 'select', selectList: notes?.{$field} || {}, title: '{$val['comment']}', templet: ea.table.switch}";
- } else {
- $templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.table.switch}";
- }
- } elseif (in_array($val['formType'], ['select', 'checkbox', 'radio', 'switch'])) {
- if (!empty($val['define'])) {
- $templateValue = "{field: '{$field}', search: 'select', selectList: notes?.{$field} || {}, title: '{$val['comment']}'}";
- } else {
- $templateValue = "{field: '{$field}', title: '{$val['comment']}'}";
- }
- } elseif ($field == 'remark') {
- $templateValue = "{field: '{$field}', title: '{$val['comment']}', templet: ea.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 = CommonTool::humpToLine($table);
- foreach ($tableVal['tableColumns'] as $field => $val) {
- if ($val['formType'] == 'image') {
- $templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.image}";
- } elseif ($val['formType'] == 'images') {
- continue;
- } elseif ($val['formType'] == 'file') {
- $templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.url}";
- } elseif ($val['formType'] == 'files') {
- continue;
- } elseif ($val['formType'] == 'editor') {
- continue;
- } elseif ($val['formType'] == 'select') {
- $templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}'}";
- } elseif ($field == 'remark') {
- $templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.table.text}";
- } elseif (in_array($field, $this->switchFields)) {
- $templateValue = "{field: '{$table}.{$field}', title: '{$val['comment']}', templet: ea.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']}'}";
- }
- if ($templateValue) $indexCols .= $this->formatColsRow("{$templateValue},\r");
- }
- }
- $recycleCols = $indexCols;
- $indexCols .= $this->formatColsRow("{width: 250, title: '操作', templet: ea.table.tool},\r");
- $jsValue = CommonTool::replaceTemplate(
- $this->getTemplate("static{$this->DS}js"),
- [
- 'controllerUrl' => $this->controllerUrl,
- 'indexCols' => $indexCols,
- 'recycleCols' => $recycleCols,
- ]
- );
- $this->fileList[$jsFile] = $jsValue;
- return $this;
- }
- /**
- * 检测文件
- * @return $this
- */
- protected function check(): static
- {
- // 是否强制性
- 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(): array
- {
- $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(): array
- {
- $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): bool
- {
- foreach ($array as $vo) {
- if (str_starts_with($vo, $string)) {
- return true;
- }
- if (str_ends_with($vo, $string)) {
- return true;
- }
- }
- return false;
- }
- /**
- * 格式化表单行
- * @param $value
- * @return string
- */
- protected function formatColsRow($value): string
- {
- return " {$value}";
- }
- /**
- * 获取对应的模板信息
- * @param $name
- * @return false|string
- */
- protected function getTemplate($name): bool|string
- {
- return file_get_contents("{$this->dir}{$this->DS}templates{$this->DS}{$name}.code");
- }
- /**
- * 检测字段注释归类的类型
- * @param string $formType
- * @return string|null
- */
- protected function checkCommentFormType(string $formType = ''): ?string
- {
- $classProperties = get_class_vars(get_class($this));
- foreach ($classProperties as $property => $classProperty) {
- if (empty($property)) continue;
- if (str_ends_with($property, 'FieldSuffix')) {
- if (in_array($formType, $this->$property)) {
- return $this->$property[0] ?? '';
- }
- }
- }
- return '';
- }
- protected function formatNotesScript(): string
- {
- return ' let notes = JSON.parse(\'{$notes|json_encode=256|raw}\');';
- }
- }
|