From be96c742ff2ed28856ee70667e04cd01e6d3a322 Mon Sep 17 00:00:00 2001
From: chenlan <18339827479@163.com>
Date: Mon, 21 Jul 2025 16:43:43 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=8F=9C=E5=8D=95url?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/common/logic/CrudLogic_bak.php | 106 -------
app/common/logic/PermLogic.php | 83 +++++-
app/common/service/CrudService.php | 143 ----------
.../traits/crud/CrudControllerTrait.php | 2 +-
.../traits/crud/CrudServiceTrait_bak2.php | 270 ------------------
app/common/utils/TableInspector.php | 57 ++++
app/common/utils/scaffold/Generate.php | 181 ++++++++++++
.../scaffold/templates/ControllerStub.stub | 0
.../utils/scaffold/templates/ModelStub.stub | 0
.../utils/scaffold/templates/ServiceStub.stub | 31 ++
.../scaffold/templates/ValidateStub.stub | 29 ++
app/common/validate/CorpValidate.php | 2 +-
app/common/validate/RoleValidate.php | 2 +-
app/controller/IndexController.php | 31 +-
14 files changed, 408 insertions(+), 529 deletions(-)
delete mode 100644 app/common/logic/CrudLogic_bak.php
delete mode 100644 app/common/service/CrudService.php
delete mode 100644 app/common/traits/crud/CrudServiceTrait_bak2.php
create mode 100644 app/common/utils/TableInspector.php
create mode 100644 app/common/utils/scaffold/Generate.php
create mode 100644 app/common/utils/scaffold/templates/ControllerStub.stub
create mode 100644 app/common/utils/scaffold/templates/ModelStub.stub
create mode 100644 app/common/utils/scaffold/templates/ServiceStub.stub
create mode 100644 app/common/utils/scaffold/templates/ValidateStub.stub
diff --git a/app/common/logic/CrudLogic_bak.php b/app/common/logic/CrudLogic_bak.php
deleted file mode 100644
index 91a4c16..0000000
--- a/app/common/logic/CrudLogic_bak.php
+++ /dev/null
@@ -1,106 +0,0 @@
-modelClass = $modelClass;
- }
-
- /**
- * 列表(带分页)
- * @param array $config CrudUtil::buildQuery 接受的配置
- * @param int $limit
- * @param int $page
- */
- public function list(array $config, int $limit, int $page)
- {
- $config['model'] = $this->modelClass;
- $query = CrudUtil::buildQuery($config);
- return CrudUtil::paginate($query, $limit, $page);
- }
-
- /**
- * 列表(不分页)
- */
- public function listAll(array $config)
- {
- $config['model'] = $this->modelClass;
- $query = CrudUtil::buildQuery($config);
- return CrudUtil::getAll($query);
- }
-
- /**
- * 根据主键查询单条
- */
- public function show($id, array $with = [])
- {
- return CrudUtil::findByPk($this->modelClass, $id, $with);
- }
-
- /**
- * 根据任意条件查询单条(可带 dataLimit)
- */
- public function showBy(array $where, array $with = [], array $dataLimit = [])
- {
- return CrudUtil::findOneBy($this->modelClass, $where, $with, $dataLimit);
- }
-
- /**
- * 创建(可带 dataLimit)
- */
- public function create(array $data, array $dataLimit = [])
- {
- return CrudUtil::create($this->modelClass, $data, $dataLimit);
- }
-
- /**
- * 主键更新(可带 dataLimit)
- */
- public function updateByPk($id, array $data, array $dataLimit = [])
- {
- return CrudUtil::updateByPk($this->modelClass, $id, $data, $dataLimit);
- }
-
- /**
- * 任意条件更新(可带 dataLimit)
- */
- public function updateBy(array $where, array $data, array $dataLimit = [])
- {
- return CrudUtil::updateBy($this->modelClass, $where, $data, $dataLimit);
- }
-
- /**
- * 主键删除
- */
- public function deleteByPk(array $ids)
- {
- return CrudUtil::deleteByPk($this->modelClass, $ids);
- }
-
- /**
- * 任意条件删除(可带 dataLimit)
- */
- public function deleteBy(array $where, array $dataLimit = [])
- {
- return CrudUtil::deleteBy($this->modelClass, $where, $dataLimit);
- }
-
- /**
- * 复杂查询回调
- * @param callable $cb function(Builder $q){ ... }
- */
- public function complex(callable $cb)
- {
- return CrudUtil::executeComplex($this->modelClass, $cb);
- }
-}
\ No newline at end of file
diff --git a/app/common/logic/PermLogic.php b/app/common/logic/PermLogic.php
index 674fbc8..16b7feb 100644
--- a/app/common/logic/PermLogic.php
+++ b/app/common/logic/PermLogic.php
@@ -60,7 +60,7 @@ class PermLogic
* @param string $parentPath
* @return array
*/
- public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array
+ public function buildTree_bak($resources, int $parentId = 0, string $parentPath = ''): array
{
$tree = [];
foreach ($resources as $node) {
@@ -121,6 +121,87 @@ class PermLogic
}
return $tree;
}
+ /**
+ * 构建目录/菜单树,节点包含权限与打开方式,拼接完整路径,并对子级菜单 component 处理
+ *
+ * @param \Illuminate\Support\Collection $resources 全部资源集合
+ * @param int $parentId 当前父级资源 ID
+ * @param string $parentPath 父级完整路径(用于递归)
+ * @return array
+ */
+ public function buildTree($resources, int $parentId = 0, string $parentPath = ''): array
+ {
+ $tree = [];
+
+ foreach ($resources as $node) {
+ if ($node->parent_id !== $parentId) {
+ continue;
+ }
+
+ // —— 拼接当前节点的完整路径 ——
+ $currentPath = $parentPath;
+ // 去掉末尾多余 slash
+ $currentPath = rtrim($currentPath, '/');
+
+ if (!empty($node->url)) {
+ // 如果当前节点有 url,则拼接
+ $urlSegment = ltrim($node->url, '/');
+ $currentPath = $currentPath === ''
+ ? $urlSegment
+ : "{$currentPath}/{$urlSegment}";
+ }
+
+ // —— 递归构建子节点 ——
+ $children = [];
+ if ($node->type === 'directory') {
+ $children = $this->buildTree($resources, $node->id, $currentPath);
+ }
+
+ // —— 收集本级的 permission 权限列表 ——
+ $authList = $resources
+ ->filter(fn($r) => $r->type === 'permission' && $r->parent_id === $node->id)
+ ->map(fn($r) => [
+ 'id' => $r->id,
+ 'title' => $r->name,
+ 'auth_mark' => $r->code,
+ ])
+ ->values()
+ ->all();
+
+ // —— 判断是否有子菜单/目录 ——
+ $hasChildrenMenu = $resources
+ ->where('parent_id', $node->id)
+ ->whereIn('type', ['directory', 'menu'])
+ ->isNotEmpty();
+
+ // —— 计算 component 字段 ——
+ if ($hasChildrenMenu) {
+ // 只要有子项,就一律显示顶层 Layout 组件
+ $componentValue = '/index/index';
+ } else {
+ // 叶子节点:如果定义了 url,就使用拼接后的路径;否则用占位符(这里用空串,你可替换)
+ $componentValue = $currentPath !== '' ? $currentPath : '';
+ }
+
+ $tree[] = [
+ 'id' => $node->id,
+ 'name' => $node->name,
+ 'path' => $node->url,
+ 'component' => $componentValue,
+ 'meta' => [
+ 'title' => $node->name,
+ 'icon' => $node->icon,
+ 'keepAlive' => true,
+ 'authList' => $authList,
+ 'openType' => $node->open_type,
+ ],
+ 'children' => $children,
+ ];
+ }
+
+ return $tree;
+ }
+
/**
* 获取用户所有权限code
diff --git a/app/common/service/CrudService.php b/app/common/service/CrudService.php
deleted file mode 100644
index 8d66a37..0000000
--- a/app/common/service/CrudService.php
+++ /dev/null
@@ -1,143 +0,0 @@
-logic = $logic;
- }
-
- /**
- * 列表接口
- * 支持前端直接传递:
- * - filter_* → where
- * - sort_by, order
- * - fields (逗号分隔)
- * - with (逗号分隔)
- * - withFields (relation:field,field;...)
- * - dataLimitType, dataLimitField
- * - limit, page
- * - complex_query=1 则调用 complexQuery()
- */
- public function list(Request $request): array
- {
- $p = $request->get();
-
- // 复杂查询开关
- if (!empty($p['complex_query']) && method_exists($this, 'complexQuery')) {
- return $this->complexQuery($p);
- }
-
- // 1. 构造 where
- $where = [];
- foreach ($p as $k => $v) {
- if (strpos($k, 'filter_') === 0 && $v !== '') {
- $col = substr($k, 7);
- // 简单等值或 like
- $where[$col] = strpos($v, '%') !== false ? ['like', $v] : $v;
- }
- }
-
- // 2. 构造其他配置
- $config = [
- 'where' => $where,
- 'order' => [($p['sort_by'] ?? 'id') => ($p['order'] ?? 'desc')],
- 'fields' => !empty($p['fields']) ? explode(',', $p['fields']) : [],
- 'with' => !empty($p['with']) ? explode(',', $p['with']) : [],
- 'withFields' => $this->parseWithFields($p['withFields'] ?? ''),
- 'dataLimit' => !empty($p['dataLimitType']) ? [
- 'type' => $p['dataLimitType'],
- 'field' => $p['dataLimitField'] ?? 'admin_id'
- ] : [],
- ];
-
- $limit = (int)($p['limit'] ?? 15);
- $page = (int)($p['page'] ?? 1);
-
- $pager = $this->logic->list($config, $limit, $page);
- return ['total' => $pager->total(), 'data' => $pager->items()];
- }
-
- /**
- * 详情
- */
- public function show($id)
- {
- return $this->logic->show($id, []);
- }
-
- /**
- * 创建
- */
- public function store(Request $request)
- {
- $data = $request->post();
- $dataLimit = $this->getDataLimitFromRequest($request);
- return $this->logic->create($data, $dataLimit);
- }
-
- /**
- * 更新
- */
- public function update(Request $request)
- {
- $key = $this->logic->modelClass::make()->getKeyName();
- $id = (int)$request->post($key);
- $data= $request->post();
- $dataLimit = $this->getDataLimitFromRequest($request);
- return $this->logic->updateByPk($id, $data, $dataLimit);
- }
-
- /**
- * 删除
- */
- public function destroy(Request $request)
- {
- $key = $this->logic->modelClass::make()->getKeyName();
- $ids = (array)$request->post($key, []);
- return $this->logic->deleteByPk($ids);
- }
-
- /** ---------- helpers ---------- */
-
- /**
- * 解析 withFields 参数 "rel:field,field;rel2:..."
- */
- protected function parseWithFields(string $str): array
- {
- if (!$str) return [];
- $out = [];
- foreach (explode(';', $str) as $pair) {
- [$rel, $flds] = explode(':', $pair);
- $out[$rel] = explode(',', $flds);
- }
- return $out;
- }
-
- /**
- * 从请求里读取 dataLimitType/Field
- */
- protected function getDataLimitFromRequest(Request $req): array
- {
- $type = $req->get('dataLimitType');
- if (!$type) return [];
- return [
- 'type' => $type,
- 'field' => $req->get('dataLimitField', 'admin_id'),
- ];
- }
-
- /**
- * 子类可重写,做复杂联表查询等
- */
- protected function complexQuery(array $params): array
- {
- throw new \LogicException('请在子类实现 complexQuery 方法');
- }
-}
\ No newline at end of file
diff --git a/app/common/traits/crud/CrudControllerTrait.php b/app/common/traits/crud/CrudControllerTrait.php
index c5cdfdc..41d9cd5 100644
--- a/app/common/traits/crud/CrudControllerTrait.php
+++ b/app/common/traits/crud/CrudControllerTrait.php
@@ -58,7 +58,7 @@ trait CrudControllerTrait
public function store(Request $request)
{
try {
- $data = $this->validate($this->service->getValidator(), $request->post(), 'create');
+ $data = $this->validate($this->service->getValidator(), $request->post(), 'store');
$res = $this->service->serviceStore($request, $data);
return $this->success($res, '创建成功');
} catch (\Exception $e) {
diff --git a/app/common/traits/crud/CrudServiceTrait_bak2.php b/app/common/traits/crud/CrudServiceTrait_bak2.php
deleted file mode 100644
index a75b28f..0000000
--- a/app/common/traits/crud/CrudServiceTrait_bak2.php
+++ /dev/null
@@ -1,270 +0,0 @@
-get('complex_query') && method_exists($this, 'complexQuery')) {
- $data = $this->complexQuery($request->get());
- } else {
- $cfg = $this->buildQueryConfig($request, 'list');
- $limit = (int)$request->get('limit', 15);
- $page = (int)$request->get('page', 1);
- $data = $this->logicList($cfg, $limit, $page);
- }
- return $this->postProcess('List', $data);
- }
-
- /** 查看单条 */
- public function serviceShow(Request $request, $id)
- {
- $item = $this->logicShow($id, []);
- return $this->postProcess('Show', $item);
- }
-
- /** 创建 */
- public function serviceStore(Request $request)
- {
- $data = $request->post();
- $dl = $this->getDataLimitFromRequest($request);
- $item = $this->logicCreate($data, $dl);
- return $this->postProcess('Store', $item);
- }
-
- /** 更新 */
- public function serviceUpdate(Request $request)
- {
- $key = (new $this->modelClass)->getKeyName();
- $id = (int)$request->post($key);
- $data = $request->post();
- $dl = $this->getDataLimitFromRequest($request);
- $item = $this->logicUpdateByPk($id, $data, $dl);
- return $this->postProcess('Update', $item);
- }
-
- /** 删除 */
- public function serviceDestroy(Request $request)
- {
- $key = (new $this->modelClass)->getKeyName();
- $ids = (array)$request->post($key, []);
- $result = $this->logicDeleteByPk($ids);
- return $this->postProcess('Destroy', $result);
- }
-
- // ---------------- 统一后置钩子 ---------------- //
-
- /**
- * 各操作后触发 afterService{Op}()
- * @param string $op List|Show|Store|Update|Destroy
- */
- protected function postProcess(string $op, mixed $data): mixed
- {
- $hook = "afterService{$op}";
- return method_exists($this, $hook)
- ? $this->{$hook}($data)
- : $data;
- }
-
- // ---------------- 复杂查询入口 ---------------- //
-
- /**
- * 子类 override 实现完全定制的复杂查询
- * @param array $params 全部请求参数
- */
- protected function complexQuery(array $params)
- {
- throw new \LogicException('请在子类实现 complexQuery()');
- }
-
- // ------------- 辅助:数据权限 & withFields 解析 ------------- //
-
- /** 从请求读取 dataLimitType & dataLimitField → ['type'=>..,'field'=>..] */
- protected function getDataLimitFromRequest(Request $req): array
- {
- $type = $req->get('dataLimitType');
- if (!$type) {
- return [];
- }
- return [
- 'type' => $type,
- 'field' => $req->get('dataLimitField', 'admin_id'),
- ];
- }
-
- /** 解析 withFields 字符串 "rel:field,field;rel2:..." */
- protected function parseWithFields(string $str): array
- {
- if (!$str) {
- return [];
- }
- $out = [];
- foreach (explode(';', $str) as $pair) {
- [$rel, $flds] = explode(':', $pair);
- $out[$rel] = explode(',', $flds);
- }
- return $out;
- }
-
- // ------------- 扁平化 Request → 查询配置 ------------- //
-
- /**
- * 构建完整配置
- * 返回 [
- * where=>[], with=>[], order=>[], withFields=>?, fields=>?, dataLimit=>[]
- * ]
- */
- protected function buildQueryConfig(Request $request, string $scene = 'list'): array
- {
- return [
- 'where' => $this->buildFilters($request, $scene),
- 'with' => $this->buildRelations($request, $scene),
- 'order' => $this->buildOrder($request, $scene),
- 'withFields' => $this->buildWithFields($request,$scene),
- 'fields' => $this->buildFields($request, $scene),
- 'dataLimit' => $this->buildDataLimit($request, $scene),
- ];
- }
-
- /**
- * 通用合并方法:取公共配置 + 场景专属配置,若均为 array 则 array_merge
- *
- * @param mixed $common 公共配置
- * @param Request $request
- * @param string $scene
- * @param string $type Filters|Relations|Order|WithFields|Fields|DataLimit
- */
- private function applySceneConfig(
- mixed $common,
- Request $request,
- string $scene,
- string $type
- ): mixed {
- $method = 'apply' . ucfirst($scene) . $type;
- if (! method_exists($this, $method)) {
- return $common;
- }
- $sceneCfg = $this->{$method}($common, $request);
- if (is_array($common) && is_array($sceneCfg)) {
- return array_merge($common, $sceneCfg);
- }
- return $sceneCfg;
- }
-
- /** 构建 WHERE:commonFilters + apply{Scene}Filters */
- protected function buildFilters(Request $r, string $scene): array
- {
- $common = $this->commonFilters($r);
- return (array)$this->applySceneConfig($common, $r, $scene, 'Filters');
- }
-
- /** 构建 with 关联 */
- protected function buildRelations(Request $r, string $scene): array
- {
- $common = $this->commonRelations();
- return (array)$this->applySceneConfig($common, $r, $scene, 'Relations');
- }
-
- /** 构建 order 排序 */
- protected function buildOrder(Request $r, string $scene): array
- {
- $common = $this->commonOrder();
- return (array)$this->applySceneConfig($common, $r, $scene, 'Order');
- }
-
- /** 构建 withFields(关联模型字段白名单) */
- protected function buildWithFields(Request $r, string $scene): ?array
- {
- $common = [];
- return $this->applySceneConfig($common, $r, $scene, 'WithFields');
- }
-
- /** 构建 fields(主表字段白名单) */
- protected function buildFields(Request $r, string $scene): ?array
- {
- $common = [];
- return $this->applySceneConfig($common, $r, $scene, 'Fields');
- }
-
- /** 构建 dataLimit(数据权限) */
- protected function buildDataLimit(Request $r, string $scene): array
- {
- $common = [];
- return (array)$this->applySceneConfig($common, $r, $scene, 'DataLimit');
- }
-
-
- // ------------- 可重写的“公共 + 场景” 方法 ------------- //
-
- // --- common* 系列(全局默认) ---
- protected function commonFilters(Request $r): array { return []; }
- protected function commonRelations(): array { return []; }
- protected function commonOrder(): array { return []; }
-
- // // --- list* 系列 ---
- // protected function applyListFilters(array $c, Request $r): array { return $this->listFilters($r); }
- // protected function listFilters(Request $r): array { return []; }
-
- // protected function applyListRelations(array $c, Request $r): array { return $this->listRelations(); }
- // protected function listRelations(): array { return []; }
-
- // protected function applyListOrder(array $c, Request $r): array { return $this->listOrder($r); }
- // protected function listOrder(Request $r): array { return ['created_at'=>'desc']; }
-
- // protected function applyListWithFields(array $c, Request $r): array{ return $this->listWithFields($r); }
- // protected function listWithFields(Request $r): array { return []; }
-
- // protected function applyListFields(array $c, Request $r): array { return $this->listFields($r); }
- // protected function listFields(Request $r): array { return []; }
-
- // protected function applyListDataLimit(array $c, Request $r): array { return $this->listDataLimit($r); }
- // protected function listDataLimit(Request $r): array { return []; }
-
- // // --- detail* 系列 ---
- // protected function applyDetailFilters(array $c, Request $r): array { return $this->detailFilters($r); }
- // protected function detailFilters(Request $r): array { return ['id'=>$r->get('id')]; }
-
- // protected function applyDetailRelations(array $c, Request $r): array { return $this->detailRelations(); }
- // protected function detailRelations(): array { return []; }
-
- // protected function applyDetailOrder(array $c, Request $r): array { return $this->detailOrder($r); }
- // protected function detailOrder(Request $r): array { return []; }
-
- // protected function applyDetailWithFields(array $c, Request $r): array{ return $this->detailWithFields($r); }
- // protected function detailWithFields(Request $r): array { return []; }
-
- // protected function applyDetailFields(array $c, Request $r): array { return $this->detailFields($r); }
- // protected function detailFields(Request $r): array { return []; }
-
- // protected function applyDetailDataLimit(array $c, Request $r): array { return $this->listDataLimit($r); }
-
- // // --- export* 系列(如有需要可 override) ---
- // protected function applyExportFilters(array $c, Request $r): array { return $this->exportFilters($r); }
- // protected function exportFilters(Request $r): array { return []; }
-}
\ No newline at end of file
diff --git a/app/common/utils/TableInspector.php b/app/common/utils/TableInspector.php
new file mode 100644
index 0000000..6b00995
--- /dev/null
+++ b/app/common/utils/TableInspector.php
@@ -0,0 +1,57 @@
+getDatabaseName();
+
+ $columns = Db::select("
+ SELECT COLUMN_NAME, DATA_TYPE, COLUMN_TYPE, IS_NULLABLE,
+ COLUMN_DEFAULT, COLUMN_COMMENT, EXTRA
+ FROM information_schema.COLUMNS
+ WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
+ ORDER BY ORDINAL_POSITION
+ ", [$database, $table]);
+
+ return array_map(function ($col) {
+ return [
+ 'name' => $col->COLUMN_NAME,
+ 'type' => $col->DATA_TYPE,
+ 'column_type' => $col->COLUMN_TYPE,
+ 'nullable' => $col->IS_NULLABLE === 'YES',
+ 'default' => $col->COLUMN_DEFAULT,
+ 'comment' => $col->COLUMN_COMMENT,
+ 'extra' => $col->EXTRA,
+ ];
+ }, $columns);
+ }
+
+ /**
+ * 获取字段名列表
+ */
+ public static function getColumnNames(string $table, ?string $database = null): array
+ {
+ return array_column(self::getColumns($table, $database), 'name');
+ }
+
+ /**
+ * 获取字段注释 map:字段名 => 注释
+ */
+ public static function getColumnComments(string $table, ?string $database = null): array
+ {
+ $columns = self::getColumns($table, $database);
+ $map = [];
+ foreach ($columns as $col) {
+ $map[$col['name']] = $col['comment'];
+ }
+ return $map;
+ }
+}
\ No newline at end of file
diff --git a/app/common/utils/scaffold/Generate.php b/app/common/utils/scaffold/Generate.php
new file mode 100644
index 0000000..d0b8a7d
--- /dev/null
+++ b/app/common/utils/scaffold/Generate.php
@@ -0,0 +1,181 @@
+options = $options;
+ }
+
+ public function doGenerate()
+ {
+ $fs = new Filesystem();
+
+ // 模板路径
+ $templateDir = __DIR__ . '/../templates/';
+ $controllerPath = __DIR__ . "/../../../{$this->options['controller']['module']}/controller/{$this->options['controller']['name']}Controller.php";
+ $servicePath = __DIR__ . "/../../../{$this->options['service']['module']}/service/{$this->options['service']['name']}Service.php";
+ $logicPath = __DIR__ . "/../../../{$this->options['logic']['module']}/service/{$this->options['logic']['name']}Service.php";
+ $modelPath = __DIR__ . "/../../../{$this->options['model']['module']}/model/{$this->options['model']['name']}.php";
+ $validatePath = __DIR__ . "/../../../{$this->options['validate']['module']}/validate/{$this->options['validate']['name']}Validate.php";
+
+ // // 创建目录(如果不存在)
+ $fs->mkdir(__DIR__ . "/../../../{$this->options['controller']['module']}/controller");
+ $fs->mkdir(__DIR__ . "/../../../{$this->options['service']['module']}/service");
+ $fs->mkdir(__DIR__ . "/../../../{$this->options['logic']['module']}/logic");
+ $fs->mkdir(__DIR__ . "/../../../{$this->options['model']['module']}/model");
+ $fs->mkdir(__DIR__ . "/../../../{$this->options['validate']['module']}/validate");
+
+ // // 删除已存在的文件并重新生成
+ $this->deleteFileIfExists($controllerPath);
+ $this->deleteFileIfExists($servicePath);
+ $this->deleteFileIfExists($logicPath);
+ $this->deleteFileIfExists($modelPath);
+ $this->deleteFileIfExists($validatePath);
+
+ // 生成控制器文件
+ $ControllerStub = $this->generateFile($templateDir, 'ControllerStub.stub', $controllerPath);
+
+ // 生成服务类文件
+ $ServiceStub = $this->generateFile($templateDir, 'ServiceStub.stub', $servicePath);
+
+ // 生成逻辑类文件
+ $LogicStub = $this->generateFile($templateDir, 'LogicStub.stub', $logicPath);
+
+ // 生成模型类文件
+ $ModelStub = $this->generateFile($templateDir, 'ModelStub.stub', $modelPath);
+
+ // 生成验证器类文件
+ $ValidatorStub = $this->generateFile($templateDir, 'ValidatorStub.stub', $validatePath);
+
+ return $ControllerStub . $ServiceStub . $LogicStub . $ModelStub . $ValidatorStub . "文件生成成功!
";
+ }
+
+ /**
+ * 设置字段
+ *
+ * @param array $fields 字段数组
+ */
+ public function fillableFields()
+ {
+ $tableName = $this->options['table'];
+ $fields = TableInspector::getColumnNames($tableName);
+ $str = '';
+ foreach ($fields as $key => $val) {
+ if ($key < (count($fields)-1)) {
+ $str .= "'{$val}', ";
+ } else {
+ $str .= "'{$val}'";
+ }
+ }
+ $fields = trim($str, '"');
+ return $fields;
+ }
+
+ /**
+ * 根据模板生成文件
+ *
+ * @param string $templateDir 模板目录
+ * @param string $templateFile 模板文件名
+ * @param string $outputPath 输出文件路径
+ */
+ protected function generateFile($templateDir, $templateFile, $outputPath)
+ {
+ $templatePath = $templateDir . $templateFile;
+
+ if (!file_exists($templatePath)) {
+ echo "模板文件 {$templateFile} 不存在! \n";
+ return;
+ }
+
+ $content = file_get_contents($templatePath);
+ $content = str_replace('{{name}}', $this->convertName, $content);
+
+ // 填入table名
+ $content = str_replace('{{table}}', $this->dbPrefix.$this->name, $content);
+
+ // 填入module名
+ $content = str_replace('{{module}}', $this->options['controller']['module'], $content);
+
+ // 填入字段
+ $content = str_replace('{{fillableFields}}', $this->fillableFields(), $content);
+
+ file_put_contents($outputPath, $content);
+
+ return "生成文件: {$outputPath}
";
+ }
+
+ /**
+ * 如果文件存在,删除它
+ *
+ * @param string $path 文件路径
+ */
+ protected function deleteFileIfExists($path)
+ {
+ if (file_exists($path)) {
+ unlink($path);
+ echo "删除已存在文件: {$path} \n";
+ }
+ }
+
+ /**
+ * 设置名称
+ */
+ public function setName($name = '')
+ {
+ $this->name = $name;
+ $this->convertName = ucfirst(camelize($name));
+ }
+
+ /**
+ * 设置模块名称
+ */
+ public function setModule($name = '')
+ {
+ $this->options['controller']['module'] = $name;
+ }
+}
+
+/**
+* 下划线转驼峰
+* 思路:
+* step1.原字符串转小写,原字符串中的分隔符用空格替换,在字符串开头加上分隔符
+* step2.将字符串中每个单词的首字母转换为大写,再去空格,去字符串首部附加的分隔符.
+*/
+function camelize($uncamelized_words, $separator='_') {
+ $uncamelized_words = $separator . str_replace($separator, " ", strtolower($uncamelized_words));
+ return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator );
+}
+
+/**
+* 驼峰命名转下划线命名
+* 思路:
+* 小写和大写紧挨一起的地方,加上分隔符,然后全部转小写
+*/
+function uncamelize($camelCaps, $separator='_') {
+ return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
+}
\ No newline at end of file
diff --git a/app/common/utils/scaffold/templates/ControllerStub.stub b/app/common/utils/scaffold/templates/ControllerStub.stub
new file mode 100644
index 0000000..e69de29
diff --git a/app/common/utils/scaffold/templates/ModelStub.stub b/app/common/utils/scaffold/templates/ModelStub.stub
new file mode 100644
index 0000000..e69de29
diff --git a/app/common/utils/scaffold/templates/ServiceStub.stub b/app/common/utils/scaffold/templates/ServiceStub.stub
new file mode 100644
index 0000000..bc01577
--- /dev/null
+++ b/app/common/utils/scaffold/templates/ServiceStub.stub
@@ -0,0 +1,31 @@
+validator;
+ }
+}
\ No newline at end of file
diff --git a/app/common/utils/scaffold/templates/ValidateStub.stub b/app/common/utils/scaffold/templates/ValidateStub.stub
new file mode 100644
index 0000000..9089654
--- /dev/null
+++ b/app/common/utils/scaffold/templates/ValidateStub.stub
@@ -0,0 +1,29 @@
+ [
+
+ ],
+
+ 'update' => [
+
+ ]
+ ];
+}
\ No newline at end of file
diff --git a/app/common/validate/CorpValidate.php b/app/common/validate/CorpValidate.php
index 5889ef9..f1710d6 100644
--- a/app/common/validate/CorpValidate.php
+++ b/app/common/validate/CorpValidate.php
@@ -29,7 +29,7 @@ class CorpValidate extends Validate
];
protected $scene = [
- 'create' => ['name', 'abbr', 'tenant_key', 'sort', 'status'],
+ 'store' => ['name', 'abbr', 'tenant_key', 'sort', 'status'],
'update' => ['id', 'name', 'abbr', 'tenant_key', 'sort', 'status']
];
}
\ No newline at end of file
diff --git a/app/common/validate/RoleValidate.php b/app/common/validate/RoleValidate.php
index afd69cc..372159f 100644
--- a/app/common/validate/RoleValidate.php
+++ b/app/common/validate/RoleValidate.php
@@ -26,7 +26,7 @@ class RoleValidate extends Validate
];
protected $scene = [
- 'create' => ['system_id', 'name', 'desc', 'sort'],
+ 'store' => ['system_id', 'name', 'desc', 'sort'],
'update' => ['id', 'system_id', 'name', 'desc', 'sort', 'status'],
];
}
diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php
index 866d3d5..b3be9af 100644
--- a/app/controller/IndexController.php
+++ b/app/controller/IndexController.php
@@ -66,12 +66,31 @@ class IndexController
}
- // test function
- public function test(Request $request)
+ public function c_()
{
- $user = User::find(1);
- $user->roles()->sync([1]);
- $user->systems()->sync([1]);
- return json(['code' => 0, 'msg' => 'success']);
+ $options = [
+ 'controller' => [
+ 'module' => 'commonName',
+ 'name' => 'ControllerName'
+ ],
+ 'model' => [
+ 'module' => 'commonName',
+ 'name' => 'modelName'
+ ],
+ 'service' => [
+ 'module' => 'commonName',
+ 'name' => 'serviceName'
+ ],
+ 'logic' => [
+ 'module' => 'commonName',
+ 'name' => 'logicName'
+ ],
+ 'validate' => [
+ 'module' => 'commonName',
+ 'name' => 'validateName'
+ ],
+ 'table' => 'tableName',
+ 'fillable' => []
+ ];
}
}
\ No newline at end of file