This commit is contained in:
zhang zhuo 2025-12-10 18:03:36 +08:00
parent 73468f9bc6
commit bfba89daba
4 changed files with 297 additions and 185 deletions

View File

@ -14,13 +14,11 @@ use App\Model\Menu as mModel;
use App\Model\Online as oModel;
use App\Model\Post as pModel;
use App\Model\Role as rModel;
use App\Model\GenTable as gtModel;
use App\Request\Account as aRequest;
use App\Request\Dept as dRequest;
use App\Request\Menu as mRequest;
use App\Request\Post as pRequest;
use App\Request\Role as rRequest;
use App\Request\GenTable as gtRequest;
use App\Model\AssetCategory as acModel;
use App\Request\AssetCategory as acRequest;
use App\Model\SystemConfig as scModel;
@ -42,15 +40,12 @@ use App\Utils\Param;
use App\Utils\RedisInfoHelper;
use App\Utils\Str;
use App\Utils\SystemHelper;
use Hyperf\Context\ApplicationContext;
use Hyperf\DbConnection\Db;
use Hyperf\Filesystem\FilesystemFactory;
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;
use function Hyperf\Config\config;
#[Controller(prefix: "admin")]
class System extends Base
@ -468,186 +463,6 @@ class System extends Base
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
#[GetMapping(path: "gen_table/list")]
#[Auth(auth: "gen_table:list")]
public function genTableList()
{
$param = Param::only(['table_name', 'table_comment', 'limit' => 10]);
return $this->success("表列表", gtModel::list($param));
}
#[GetMapping(path: "gen_table/info")]
#[Auth(auth: "gen_table:info")]
public function genTableInfo()
{
$id = $this->request->input("id");
return $this->success("详情", gtModel::info($id));
}
#[PostMapping(path: "gen_table/edit")]
#[Auth(auth: "gen_table:edit")]
public function genTableEdit()
{
$request = $this->container->get(gtRequest::class);
$request->scene('edit')->validateResolved();
$param = Param::only(['table_id', 'table_name', 'table_comment', 'controller_name', 'module_name', 'remark', 'gen_table_columns']);
return $this->toAjax(gtModel::editData($param));
}
#[DeleteMapping(path: "gen_table/del")]
#[Auth(auth: "gen_table:del")]
public function genTableDel()
{
$param = Param::only(['ids' => []]);
return $this->toAjax(gtModel::del($param['ids']));
}
#[GetMapping(path: "gen_table/select")]
#[Auth(auth: "gen_table:select")]
public function genTableSelect()
{
$param = Param::only(['table_name', 'table_comment', 'limit' => 10, 'page' => 1]);
$offset = ($param['page'] - 1) * $param['limit'];
// 获取所有表
$rows = Db::select("SHOW TABLE STATUS");
// 获取已经导入的表
$tables = gtModel::pluck("table_name")->toArray();
// 表前缀
$prefix = config("databases.default.prefix");
// 构建表不导入 gen_table gen_table_column
$tables = array_merge([$prefix . "gen_table", $prefix . "gen_table_column"], $tables);
$rows = array_filter($rows, function ($item) use ($tables, $param) {
// 过滤表
if (in_array($item->Name, $tables)) {
return false;
}
// 表名筛选
if (isset($param['table_name']) && $param['table_name'] != "" && !str_contains($item->Name, $param['table_name'])) {
return false;
}
// 表描述筛选
if (isset($param['table_comment']) && $param['table_comment'] != "" && !str_contains($item->Comment, $param['table_comment'])) {
return false;
}
return true;
});
$count = count($rows);
$rows = array_slice($rows, $offset, $param['limit']);
// 过滤返回数据
$data = [];
foreach ($rows as $row) {
$data[] = [
'table_name' => $row->Name,
'table_comment' => $row->Comment,
'create_time' => $row->Create_time,
'update_time' => $row->Update_time
];
}
return $this->success("表列表", $data, $count);
}
#[PostMapping(path: "gen_table/build")]
#[Auth(auth: "gen_table:build")]
public function genTableBuild()
{
// 生成表数据
$param = Param::only(['names' => []]);
if (empty($param['names'])) {
return $this->error("数据表不为空");
}
// 获取已经导入的表
$tables = gtModel::pluck("table_name")->toArray();
// 表前缀
$prefix = config("databases.default.prefix");
// 构建表不导入 gen_table gen_table_column
$tables = array_merge([$prefix . "gen_table", $prefix . "gen_table_column"], $tables);
// 获取所有表
$rows = Db::select("SHOW TABLE STATUS");
// 去重
$rows = array_filter($rows, function ($item) use ($tables, $param) {
// 过滤表
if (in_array($item->Name, $tables)) {
return false;
}
// 表筛选
return in_array($item->Name, $param['names']);
});
if (empty($rows)) {
return $this->error("数据表不为空");
}
// 生成数据
$res = gtModel::genTable($rows);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
#[PostMapping(path: "gen_table/sync")]
#[Auth(auth: "gen_table:sync")]
public function genTableSync()
{
$table_id = $this->request->input("id");
if (!$table_id) {
return $this->error("同步失败");
}
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']);
preg_match_all('/([a-zA-Z])[a-zA-Z]*/', $table_name, $m);
$name1 = implode('', $m[1]);
$name2 = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $table_name))));
$module_name = $table['module_name'];
$controller_name = $table['controller_name'];
// 搜搜字段
$query_fields = [];
$insert_fields = [];
$edit_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", "name1", "name2")),
'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', 'name2')),
'save.vue' => $this->render->getContents('templates/save.vue.twig', compact('table_name', 'insert_fields', 'required_fields', 'edit_fields'))
];
return $this->success("模板信息", $data);
}
#[GetMapping(path: "asset_category/list")]
#[Auth(needAuth: false)]
public function assetCategoryList()

View File

@ -0,0 +1,219 @@
<?php
namespace App\Controller\Admin;
use App\Annotation\Auth;
use App\Model\GenTable as gtModel;
use App\Request\GenTable as gtRequest;
use App\Utils\Param;
use Hyperf\DbConnection\Db;
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;
use function Hyperf\Config\config;
#[Controller(prefix: "admin")]
class Tools extends Base
{
#[GetMapping(path: "gen_table/list")]
#[Auth(auth: "gen_table:list")]
public function genTableList()
{
$param = Param::only(['table_name', 'table_comment', 'limit' => 10]);
return $this->success("表列表", gtModel::list($param));
}
#[GetMapping(path: "gen_table/info")]
#[Auth(auth: "gen_table:info")]
public function genTableInfo()
{
$id = $this->request->input("id");
return $this->success("详情", gtModel::info($id));
}
#[PostMapping(path: "gen_table/edit")]
#[Auth(auth: "gen_table:edit")]
public function genTableEdit()
{
$request = $this->container->get(gtRequest::class);
$request->scene('edit')->validateResolved();
$param = Param::only(['table_id', 'table_name', 'table_comment', 'controller_name', 'module_name', 'remark', 'gen_table_columns']);
return $this->toAjax(gtModel::editData($param));
}
#[DeleteMapping(path: "gen_table/del")]
#[Auth(auth: "gen_table:del")]
public function genTableDel()
{
$param = Param::only(['ids' => []]);
return $this->toAjax(gtModel::del($param['ids']));
}
#[GetMapping(path: "gen_table/select")]
#[Auth(auth: "gen_table:select")]
public function genTableSelect()
{
$param = Param::only(['table_name', 'table_comment', 'limit' => 10, 'page' => 1]);
$offset = ($param['page'] - 1) * $param['limit'];
// 获取所有表
$rows = Db::select("SHOW TABLE STATUS");
// 获取已经导入的表
$tables = gtModel::pluck("table_name")->toArray();
// 表前缀
$prefix = config("databases.default.prefix");
// 构建表不导入 gen_table gen_table_column
$tables = array_merge([$prefix . "gen_table", $prefix . "gen_table_column"], $tables);
$rows = array_filter($rows, function ($item) use ($tables, $param) {
// 过滤表
if (in_array($item->Name, $tables)) {
return false;
}
// 表名筛选
if (isset($param['table_name']) && $param['table_name'] != "" && !str_contains($item->Name, $param['table_name'])) {
return false;
}
// 表描述筛选
if (isset($param['table_comment']) && $param['table_comment'] != "" && !str_contains($item->Comment, $param['table_comment'])) {
return false;
}
return true;
});
$count = count($rows);
$rows = array_slice($rows, $offset, $param['limit']);
// 过滤返回数据
$data = [];
foreach ($rows as $row) {
$data[] = [
'table_name' => $row->Name,
'table_comment' => $row->Comment,
'create_time' => $row->Create_time,
'update_time' => $row->Update_time
];
}
return $this->success("表列表", $data, $count);
}
#[PostMapping(path: "gen_table/build")]
#[Auth(auth: "gen_table:build")]
public function genTableBuild()
{
// 生成表数据
$param = Param::only(['names' => []]);
if (empty($param['names'])) {
return $this->error("数据表不为空");
}
// 获取已经导入的表
$tables = gtModel::pluck("table_name")->toArray();
// 表前缀
$prefix = config("databases.default.prefix");
// 构建表不导入 gen_table gen_table_column
$tables = array_merge([$prefix . "gen_table", $prefix . "gen_table_column"], $tables);
// 获取所有表
$rows = Db::select("SHOW TABLE STATUS");
// 去重
$rows = array_filter($rows, function ($item) use ($tables, $param) {
// 过滤表
if (in_array($item->Name, $tables)) {
return false;
}
// 表筛选
return in_array($item->Name, $param['names']);
});
if (empty($rows)) {
return $this->error("数据表不为空");
}
// 生成数据
$res = gtModel::genTable($rows);
return $res ? $this->success("操作成功") : $this->error("操作失败");
}
#[PostMapping(path: "gen_table/sync")]
#[Auth(auth: "gen_table:sync")]
public function genTableSync()
{
$table_id = $this->request->input("id");
if (!$table_id) {
return $this->error("同步失败");
}
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']);
preg_match_all('/([a-zA-Z])[a-zA-Z]*/', $table_name, $m);
$name1 = implode('', $m[1]);
$name2 = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $table_name))));
$module_name = $table['module_name'];
$controller_name = $table['controller_name'];
// 搜搜字段
$query_fields = [];
$insert_fields = [];
$edit_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", "name1", "name2")),
'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', 'name2')),
'save.vue' => $this->render->getContents('templates/save.vue.twig', compact('table_name', 'insert_fields', 'required_fields', 'edit_fields'))
];
return $this->success("模板信息", $data);
}
#[PostMapping(path: "form/build")]
#[Auth(auth: "form:build")]
public function formBuild()
{
$param = Param::only(['fields' => [], 'config' => []]);
if (empty($param['fields']) || empty($param['config'])) {
return $this->error("生成失败,重要参数未传递");
}
if (isset($param['config']['isMobile']) && $param['config']['isMobile']) {
$data = [
'form.vue' => $this->render->getContents('templates/formMobile.vue.twig', $param)
];
} else {
$data = [
'form.vue' => $this->render->getContents('templates/formDesktop.vue.twig', $param)
];
}
return $this->success("表单信息", $data);
}
}

View File

@ -0,0 +1,78 @@
<template>
<el-dialog :title="titleMap[mode]" v-model="visible" :width="800" destroy-on-close @closed="$emit('closed')">
<el-form :model="{{ config.model }}" :rules="{{ config.rules }}" :disabled="mode==='show'" ref="{{ config.ref }}"
label-width="{{ config.labelWidth }}" label-position="{{ config.labelPosition }}" size="{{ config.size }}">
{% for field in fields %}
<el-form-item label="{{ field.title }}" prop="{{ field.field_name }}">
{% if field.name == 'text' %}
<el-input v-model="{{ config.model }}.{{ field.field_name }}"{% if field.props.placeholder %} placeholder="{{ field.props.placeholder }}"{% endif %}
{% if field.props.minlength %} :minlength="{{ field.props.minlength }}"{% endif %}{% if field.props.maxlength %} :maxlength="{{ field.props.maxlength }}"{% endif %}
{% if field.props.showWordLimit %} showWordLimit{% endif %}{% if field.props.prefixIcon %} prefixIcon="{{ field.props.prefixIcon }}"{% endif %}
{% if field.props.suffixIcon %} suffixIcon="{{ field.props.suffixIcon }}"{% endif %}{% if field.props.clearable %} clearable{% endif %}
{% if field.props.readonly %} readonly{% endif %}{% if field.props.disabled %} disabled{% endif %}{% if field.width %} style="width: {{ field.width }}"{% endif %}/>
{% endif %}
</el-form-item>
{% endfor %}
</el-form>
<template #footer>
<el-button @click="visible=false">取 消</el-button>
<el-button v-if="mode!=='show'" type="primary" :loading="isSaveing" @click="submit()">保 存</el-button>
</template>
</el-dialog>
</template>
<script setup>
import {getCurrentInstance, ref} from 'vue'
import api from "@/api/index"
defineExpose({
open
})
const emit = defineEmits(['success', 'closed'])
const formRef = ref(null)
const {proxy} = getCurrentInstance()
let mode = ref('add')
let titleMap = ref({
add: '新增',
edit: '编辑',
show: '查看'
})
let visible = ref(false)
let isSaveing = ref(false)
let form = ref({
dict_id: null,
dict_name: null,
dict_type: null,
remark: null
})
const rules = ref({
dict_name: [
{required: true, message: '请填写字典名称'}
],
dict_type: [
{required: true, message: '请填写字典类型'}
]
})
function open(m = 'add', data = null) {
mode.value = m
visible.value = true
Object.assign(form.value, data)
}
async function submit() {
// 校验登录
const validate = await formRef.value.validate().catch(() => {
});
if (!validate) {
return false
}
isSaveing.value = true;
const res = form.value.dict_id ? await api.system.dict.edit(form.value) : await api.system.dict.add(form.value);
isSaveing.value = false;
emit('success')
visible.value = false;
proxy.$message.success(res.msg)
}
</script>