diff --git a/app/Controller/AbstractController.php b/app/Controller/AbstractController.php index ca509f8..4ce7b3e 100644 --- a/app/Controller/AbstractController.php +++ b/app/Controller/AbstractController.php @@ -7,6 +7,7 @@ namespace App\Controller; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Contract\RequestInterface; use Hyperf\HttpServer\Contract\ResponseInterface; +use Hyperf\View\RenderInterface; use Psr\Container\ContainerInterface; use Psr\EventDispatcher\EventDispatcherInterface; @@ -23,4 +24,7 @@ abstract class AbstractController #[Inject] protected EventDispatcherInterface $eventDispatcher; + + #[Inject] + protected RenderInterface $render; } diff --git a/app/Controller/Admin/System.php b/app/Controller/Admin/System.php index bfe7dfa..932c0a4 100644 --- a/app/Controller/Admin/System.php +++ b/app/Controller/Admin/System.php @@ -578,4 +578,56 @@ class System extends Base } return $this->toAjax(gtModel::syncTable($table_id)); } + + #[GetMapping(path: "gen_table/show")] + #[Auth(auth: "gen_table:show")] + public function genTableShow() + { + $table_id = $this->request->input("id"); + if (!$table_id) { + return $this->error("生成失败"); + } + $table = gtModel::info($table_id); + if (empty($table)) { + return $this->error("生成失败"); + } + // 表前缀 + $prefix = config("databases.default.prefix"); + // 表名 + $table_name = str_replace($prefix, "", $table['table_name']); + $module_name = $table['module_name']; + $controller_name = $table['controller_name']; + // 搜搜字段 + $query_fields = []; + $insert_fields = []; + $list_fields = []; + $required_fields = []; + $fields = $table['gen_table_columns']; + foreach ($fields as $column) { + if ($column['is_query']) { + $query_fields[] = $column; + } + if ($column['is_insert'] && !in_array($column['column_name'], ['create_time', 'update_time', 'deleted_at'])) { + $insert_fields[] = $column; + } + if ($column['is_edit'] && !in_array($column['column_name'], ['create_time', 'update_time', 'deleted_at'])) { + $edit_fields[] = $column; + } + if ($column['is_list']) { + $list_fields[] = $column; + } + if ($column['is_required'] && !in_array($column['column_name'], ['create_time', 'update_time', 'deleted_at'])) { + $required_fields[] = $column; + } + } + $data = [ + 'model.php' => $this->render->getContents('templates/model.php.twig', compact("table_name", "fields", "controller_name", "query_fields", "list_fields")), + 'request.php' => $this->render->getContents('templates/request.php.twig', compact("controller_name", "insert_fields", "fields", "required_fields", "edit_fields")), + 'controller.php' => $this->render->getContents('templates/controller.php.twig', compact("controller_name", "module_name", "query_fields", "insert_fields", "edit_fields", "table_name")), + 'api.ts' => $this->render->getContents('templates/api.ts.twig', compact('table_name')), + 'index.vue' => $this->render->getContents('templates/index.vue.twig', compact('table_name', 'list_fields', 'query_fields')), + 'save.vue' => $this->render->getContents('templates/save.vue.twig', compact('table_name', 'insert_fields', 'required_fields')) + ]; + return $this->success("模板信息", $data); + } } \ No newline at end of file diff --git a/app/Model/GenTable.php b/app/Model/GenTable.php index 3f68040..626c155 100644 --- a/app/Model/GenTable.php +++ b/app/Model/GenTable.php @@ -4,7 +4,6 @@ declare(strict_types=1); namespace App\Model; -use App\Exception\ServiceException; use App\Utils\Str; use Hyperf\DbConnection\Db; @@ -66,6 +65,7 @@ class GenTable extends Model Db::rollBack(); return false; } + // 字段管理 $columns = Db::select("SHOW FULL COLUMNS FROM `{$row->Name}`"); $i = 1; diff --git a/composer.json b/composer.json index 8468f87..c3fc680 100644 --- a/composer.json +++ b/composer.json @@ -32,8 +32,10 @@ "hyperf/rate-limit": "^3.1", "hyperf/redis": "~3.1.0", "hyperf/validation": "^3.1", + "hyperf/view": "^3.1", "hyperf/websocket-server": "^3.1", "phpoffice/phpspreadsheet": "^4.5", + "twig/twig": "^3.22", "zoujingli/ip2region": "^3.0" }, "require-dev": { diff --git a/config/autoload/view.php b/config/autoload/view.php new file mode 100644 index 0000000..135e3cd --- /dev/null +++ b/config/autoload/view.php @@ -0,0 +1,14 @@ + Hyperf\View\Engine\TwigEngine::class, + 'mode' => Mode::SYNC, + 'config' => [ + 'view_path' => BASE_PATH . '/static/view/', + 'cache_path' => BASE_PATH . '/runtime/view/' + ] +]; diff --git a/static/view/templates/api.ts.twig b/static/view/templates/api.ts.twig new file mode 100644 index 0000000..6f4dd12 --- /dev/null +++ b/static/view/templates/api.ts.twig @@ -0,0 +1,24 @@ +import http from "@/utils/request" + +export default { + {{ table_name }}: { + list: async function (data = {}) { + return await http.get("{{ table_name }}/list", data); + }, + info: async function (data = {}) { + return await http.get("{{ table_name }}/list", data); + }, + add: async function (data = {}) { + return await http.post("{{ table_name }}/add", data); + }, + edit: async function (data = {}) { + return await http.put("{{ table_name }}/edit", data); + }, + del: async function (data = {}) { + return await http.delete("{{ table_name }}/del", data); + }, + option: async function (data = {}) { + return await http.get("{{ table_name }}/option", data); + }, + }, +} diff --git a/static/view/templates/controller.php.twig b/static/view/templates/controller.php.twig new file mode 100644 index 0000000..97f9279 --- /dev/null +++ b/static/view/templates/controller.php.twig @@ -0,0 +1,71 @@ + +*/ + +namespace {{ module_name }}; + +use App\Annotation\Auth; +use App\Model\{{ controller_name }} as {{ table_name | slice(0, 1) }}Model; +use App\Request\{{ controller_name }} as {{ table_name | slice(0, 1) }}Request; +use App\Utils\Param; +use Hyperf\HttpServer\Annotation\Controller; +use Hyperf\HttpServer\Annotation\DeleteMapping; +use Hyperf\HttpServer\Annotation\GetMapping; +use Hyperf\HttpServer\Annotation\PostMapping; +use Hyperf\HttpServer\Annotation\PutMapping; + +#[Controller(prefix: "admin")] +class {{ controller_name }} extends Base +{ + #[GetMapping(path: "{{ table_name }}/list")] + #[Auth(auth: "{{ table_name }}:list")] + public function {{ table_name }}List() + { + $param = Param::only([{% for field in query_fields %}"{{ field.column_name }}"{% if not loop.last %}, {% endif %}{% endfor %}]); + return $this->success({{ table_name | slice(0, 1) }}Model::list($param)); + } + + #[GetMapping(path: "{{ table_name }}/option")] + #[Auth(needAuth: false)] + public function {{ table_name }}Option() + { + return $this->success({{ table_name | slice(0, 1) }}Model::options()); + } + + #[GetMapping(path: "{{ table_name }}/info")] + #[Auth(auth: "{{ table_name }}:info")] + public function {{ table_name }}Info() + { + $id = $this->request->input("id"); + return $this->success({{ table_name | slice(0, 1) }}Model::getById()); + } + + #[PostMapping(path: "{{ table_name }}/add")] + #[Auth(auth: "{{ table_name }}:add")] + public function {{ table_name }}Add() + { + $request = $this->container->get({{ table_name | slice(0, 1)}}Request::class); + $request->scene('add')->validateResolved(); + $data = Param::only([{% for field in insert_fields %}"{{ field.column_name }}"{% if not loop.last %}, {% endif %}{% endfor %}]); + return $this->toAjax({{ table_name | slice(0, 1) }}Model::add($data)); + } + + #[PutMapping(path: "{{ table_name }}/edit")] + #[Auth(auth: "{{ table_name }}:edit")] + public function {{ table_name }}Edit() + { + $request = $this->container->get({{ table_name | slice(0, 1)}}Request::class); + $request->scene('edit')->validateResolved(); + $data = Param::only([{% for field in edit_fields %}"{{ field.column_name }}"{% if not loop.last %}, {% endif %}{% endfor %}]); + return $this->toAjax({{ table_name | slice(0, 1) }}Model::edit($data)); + } + + #[DeleteMapping(path: "{{ table_name }}/del")] + #[Auth(auth: "{{ table_name }}:del")] + public function {{ table_name }}Del() + { + $ids = $this->request->input("ids"); + return $this->toAjax({{ table_name | slice(0, 1) }}Model::del($ids)); + } +} \ No newline at end of file diff --git a/static/view/templates/index.vue.twig b/static/view/templates/index.vue.twig new file mode 100644 index 0000000..c1ce8cc --- /dev/null +++ b/static/view/templates/index.vue.twig @@ -0,0 +1,170 @@ + + + diff --git a/static/view/templates/model.php.twig b/static/view/templates/model.php.twig new file mode 100644 index 0000000..ba107c3 --- /dev/null +++ b/static/view/templates/model.php.twig @@ -0,0 +1,78 @@ + 'integer'{% set first = false %}{% endif %}{% endfor %}]; + + public static function list(array $param) + { + $model = self::query(); +{% for field in query_fields %} +{% if field.query_type == 'eq' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', $param['{{ field.column_name }}']); + } +{% elseif field.query_type == 'neq' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', "<>", $param['{{ field.column_name }}']); + } +{% elseif field.query_type == 'gt' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', ">", $param['{{ field.column_name }}']); + } +{% elseif field.query_type == 'lt' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', "<", $param['{{ field.column_name }}']); + } +{% elseif field.query_type == 'gte' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', ">=", $param['{{ field.column_name }}']); + } +{% elseif field.query_type == 'lte' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', "<=", $param['{{ field.column_name }}']); + } +{% elseif field.query_type == 'like' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', "like", "%{$param['{{ field.column_name }}']}%"); + } +{% elseif field.query_type == 'between' %} + if (isset($param['{{ field.column_name }}']) && $param['{{ field.column_name }}'] != '') { + $model = $model->where('{{field.column_name}}', "between", $param['{{ field.column_name }}']); + } +{% endif %} +{% endfor %} + return $model->orderByDesc("{{ table_name }}_id") + ->select([{% for field in list_fields %}"{{ field.column_name }}"{% if not loop.last %}, {% endif %}{% endfor %}]) + ->paginate((int)$param['limit']); + } + + public static function options() + { + return self::select(["{{ table_name }}_id", "{{ table_name }}_name"])->get()->toArray(); + } +} diff --git a/static/view/templates/request.php.twig b/static/view/templates/request.php.twig new file mode 100644 index 0000000..33da3da --- /dev/null +++ b/static/view/templates/request.php.twig @@ -0,0 +1,42 @@ + [{% for field in insert_fields %}"{{ field.column_name }}"{% if not loop.last %}, {% endif %}{% endfor %}], + 'edit' => [{% for field in edit_fields %}"{{ field.column_name }}"{% if not loop.last %}, {% endif %}{% endfor %}], + ]; + + /** + * Determine if the user is authorized to make this request. + */ + public function authorize(): bool + { + return true; + } + + /** + * Get the validation rules that apply to the request. + */ + public function rules(): array + { + return [ +{% for field in fields %} + '{{ field.column_name }}' => 'required', +{% endfor %} + ]; + } + + public function messages(): array + { + return [ +{% for field in edit_fields %} + '{{ field.column_name }}.required' => '{{ field.column_comment }}必传!', +{% endfor %} + ]; + } +} diff --git a/static/view/templates/save.vue.twig b/static/view/templates/save.vue.twig new file mode 100644 index 0000000..b677318 --- /dev/null +++ b/static/view/templates/save.vue.twig @@ -0,0 +1,100 @@ + + + diff --git a/watcher.php b/watcher.php new file mode 100644 index 0000000..9f19cd0 --- /dev/null +++ b/watcher.php @@ -0,0 +1,16 @@ + ScanFileDriver::class, + 'bin' => PHP_BINARY, + 'watch' => [ + 'dir' => ['app', 'config'], + 'file' => ['.env'], + 'scan_interval' => 2000, + ], + 'ext' => ['.php', '.env'], +];