diff --git a/frontend/package.json b/frontend/package.json index b15f1bba..c9192eec 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -131,6 +131,7 @@ "postcss": "^8.5.6", "postcss-html": "^1.8.0", "postcss-scss": "^4.0.9", + "plop": "^4.0.1", "prettier": "^3.6.2", "sass": "^1.89.2", "stylelint": "^16.25.0", diff --git a/frontend/plop-templates/curd-list-page.vue.hbs b/frontend/plop-templates/curd-list-page.vue.hbs new file mode 100644 index 00000000..0f41654f --- /dev/null +++ b/frontend/plop-templates/curd-list-page.vue.hbs @@ -0,0 +1,85 @@ + + + + diff --git a/frontend/plopfile.mjs b/frontend/plopfile.mjs new file mode 100644 index 00000000..ade16a07 --- /dev/null +++ b/frontend/plopfile.mjs @@ -0,0 +1,31 @@ +/** @param {import("plop").NodePlopAPI} plop */ +export default function (plop) { + plop.setGenerator("curd-list", { + description: "列表页骨架:PageSearch + PageContent + CrudToolbarLeft/Right + useCrudList", + prompts: [ + { + type: "input", + name: "modulePath", + message: "views 下路径(如 module_example/demo)", + }, + { + type: "input", + name: "componentName", + message: "组件 name(PascalCase,如 Demo)", + }, + { + type: "input", + name: "permPrefix", + message: "权限前缀(如 module_example:demo)", + }, + ], + actions: [ + { + type: "add", + path: "src/views/{{modulePath}}/index.vue", + templateFile: "plop-templates/curd-list-page.vue.hbs", + skipIfExists: true, + }, + ], + }); +} diff --git a/frontend/src/components/CURD/CrudToolbarLeft.vue b/frontend/src/components/CURD/CrudToolbarLeft.vue new file mode 100644 index 00000000..9d0707f3 --- /dev/null +++ b/frontend/src/components/CURD/CrudToolbarLeft.vue @@ -0,0 +1,92 @@ + + + + diff --git a/frontend/src/components/CURD/CrudToolbarRight.vue b/frontend/src/components/CURD/CrudToolbarRight.vue new file mode 100644 index 00000000..c6c59cf8 --- /dev/null +++ b/frontend/src/components/CURD/CrudToolbarRight.vue @@ -0,0 +1,57 @@ + + + + diff --git a/frontend/src/components/CURD/EnhancedDialog.vue b/frontend/src/components/CURD/EnhancedDialog.vue new file mode 100644 index 00000000..1e27f50a --- /dev/null +++ b/frontend/src/components/CURD/EnhancedDialog.vue @@ -0,0 +1,112 @@ + + + + + diff --git a/frontend/src/components/CURD/EnhancedDrawer.vue b/frontend/src/components/CURD/EnhancedDrawer.vue new file mode 100644 index 00000000..61ba3925 --- /dev/null +++ b/frontend/src/components/CURD/EnhancedDrawer.vue @@ -0,0 +1,102 @@ + + + + + diff --git a/frontend/src/components/CURD/ExportModal.vue b/frontend/src/components/CURD/ExportModal.vue index 546fd5aa..628d6967 100644 --- a/frontend/src/components/CURD/ExportModal.vue +++ b/frontend/src/components/CURD/ExportModal.vue @@ -1,12 +1,11 @@ - + diff --git a/frontend/src/components/CURD/PageModal.vue b/frontend/src/components/CURD/PageModal.vue index 3b8195ae..45cc2991 100644 --- a/frontend/src/components/CURD/PageModal.vue +++ b/frontend/src/components/CURD/PageModal.vue @@ -66,9 +66,12 @@ - + diff --git a/frontend/src/views/module_example/demo/index.vue b/frontend/src/views/module_example/demo/index.vue index 70e1283a..e9e15cee 100644 --- a/frontend/src/views/module_example/demo/index.vue +++ b/frontend/src/views/module_example/demo/index.vue @@ -1,423 +1,248 @@ - + @@ -625,33 +431,110 @@ defineOptions({ inheritAttrs: false, }); -import { ref, reactive, onMounted } from "vue"; -import { ElMessage, ElMessageBox } from "element-plus"; +import { ref, reactive, onMounted, markRaw, nextTick } from "vue"; +import { fetchAllPages } from "@/utils/fetchAllPages"; +import { ElMessageBox } from "element-plus"; import { ResultEnum } from "@/enums/api/result.enum"; import DemoAPI, { DemoTable, DemoForm, DemoPageQuery } from "@/api/module_example/demo"; -import ImportModal from "@/components/CURD/ImportModal.vue"; -import ExportModal from "@/components/CURD/ExportModal.vue"; -import DatePicker from "@/components/DatePicker/index.vue"; -import type { IContentConfig } from "@/components/CURD/types"; -import { ArrowUp, ArrowDown } from "@element-plus/icons-vue"; -import { formatToDateTime } from "@/utils/dateUtil"; +import CrudToolbarLeft from "@/components/CURD/CrudToolbarLeft.vue"; +import CrudToolbarRight from "@/components/CURD/CrudToolbarRight.vue"; +import PageSearch from "@/components/CURD/PageSearch.vue"; +import PageContent from "@/components/CURD/PageContent.vue"; +import EnhancedDialog from "@/components/CURD/EnhancedDialog.vue"; +import { useCrudList } from "@/components/CURD/useCrudList"; +import UserTableSelect from "@/views/module_system/user/components/UserTableSelect.vue"; +import type { IContentConfig, ISearchConfig } from "@/components/CURD/types"; +import JsonPretty from "@/components/JsonPretty/index.vue"; -const visible = ref(true); -const queryFormRef = ref(); -const dataFormRef = ref(); -const total = ref(0); -const selectIds = ref([]); -const selectionRows = ref([]); -const loading = ref(false); -const isExpand = ref(false); -const isExpandable = ref(true); -const metadataList = ref<{ key: string; value: string }[]>([]); +const { searchRef, contentRef, handleQueryClick, handleResetClick, refreshList } = useCrudList(); -// 分页表单 -const pageTableData = ref([]); +function triggerUserSearch() { + nextTick(() => refreshList()); +} -// 表格列配置 -const tableColumns = ref([ +const searchConfig = reactive({ + permPrefix: "module_example:demo", + colon: true, + isExpandable: true, + showNumber: 2, + showToggle: false, + form: { labelWidth: "auto" }, + formItems: [ + { + prop: "name", + label: "名称", + type: "input", + attrs: { placeholder: "请输入名称", clearable: true }, + }, + { + prop: "status", + label: "状态", + type: "select", + options: [ + { label: "启用", value: "0" }, + { label: "停用", value: "1" }, + ], + attrs: { placeholder: "请选择状态", clearable: true, style: { width: "170px" } }, + }, + { + prop: "created_id", + label: "创建人", + type: "user-table-select", + initialValue: null, + events: { + "confirm-click": triggerUserSearch, + "clear-click": triggerUserSearch, + }, + }, + { + prop: "updated_id", + label: "更新人", + type: "user-table-select", + initialValue: null, + events: { + "confirm-click": triggerUserSearch, + "clear-click": triggerUserSearch, + }, + }, + { + prop: "created_time", + label: "创建时间", + type: "date-picker", + initialValue: [], + attrs: { + type: "datetimerange", + valueFormat: "YYYY-MM-DD HH:mm:ss", + rangeSeparator: "至", + startPlaceholder: "开始", + endPlaceholder: "结束", + }, + }, + { + prop: "updated_time", + label: "更新时间", + type: "date-picker", + initialValue: [], + attrs: { + type: "datetimerange", + valueFormat: "YYYY-MM-DD HH:mm:ss", + rangeSeparator: "至", + startPlaceholder: "开始", + endPlaceholder: "结束", + }, + }, + ], + customComponents: { + "user-table-select": markRaw(UserTableSelect), + }, +}); + +const contentCols = reactive< + Array<{ + prop?: string; + label?: string; + show?: boolean; + }> +>([ { prop: "selection", label: "选择框", show: true }, { prop: "index", label: "序号", show: true }, { prop: "name", label: "名称", show: true }, @@ -674,89 +557,74 @@ const tableColumns = ref([ { prop: "operation", label: "操作", show: true }, ]); -// 仅用于导出字段的列(排除非数据列及嵌套对象列) -const exportColumns = [ - { prop: "name", label: "名称" }, - { prop: "uuid", label: "UUID" }, - { prop: "status", label: "状态" }, - { prop: "a", label: "整数" }, - { prop: "b", label: "大整数" }, - { prop: "c", label: "浮点数" }, - { prop: "d", label: "布尔值" }, - { prop: "e", label: "日期" }, - { prop: "f", label: "时间" }, - { prop: "g", label: "日期时间" }, - { prop: "h", label: "长文本" }, - { prop: "i", label: "元数据" }, - { prop: "description", label: "描述" }, - { prop: "created_time", label: "创建时间" }, - { prop: "updated_time", label: "更新时间" }, -]; +function normalizeDemoQuery(params: Record) { + const p = { ...params } as Record; + if (Array.isArray(p.created_time) && p.created_time.length === 0) p.created_time = undefined; + if (Array.isArray(p.updated_time) && p.updated_time.length === 0) p.updated_time = undefined; + return p as unknown as DemoPageQuery; +} -// 导入/导出配置 -const curdContentConfig = { +const contentConfig = reactive>({ permPrefix: "module_example:demo", - cols: exportColumns as any, + hideColumnFilter: false, + initialFetch: false, + cols: contentCols as IContentConfig["cols"], + toolbar: [], + defaultToolbar: ["import", "exports", "search", "refresh", "filter"], + pagination: { + pageSize: 10, + pageSizes: [10, 20, 30, 50], + }, + request: { page_no: "page_no", page_size: "page_size" }, + indexAction: async (params) => { + const res = await DemoAPI.getDemoList( + normalizeDemoQuery(params as unknown as Record) + ); + return { + total: res.data.data.total, + list: res.data.data.items, + }; + }, + deleteAction: (ids) => + DemoAPI.deleteDemo( + ids + .split(",") + .map((s) => Number(s.trim())) + .filter((n) => !Number.isNaN(n) && n > 0) + ), importTemplate: () => DemoAPI.downloadTemplateDemo(), - exportsAction: async (params: any) => { - const query: any = { ...params }; + importAction: (file: File) => { + const fd = new FormData(); + fd.append("file", file); + return DemoAPI.importDemo(fd).then((res) => { + if (res.data.code !== ResultEnum.SUCCESS) { + return Promise.reject(new Error(res.data.msg)); + } + }); + }, + exportsAction: async (params: DemoPageQuery) => { + const query: Record = { ...params }; if (typeof query.status === "string") { query.status = query.status === "true"; } - query.page_no = 1; - query.page_size = 9999; - const all: any[] = []; - while (true) { - const res = await DemoAPI.getDemoList(query); - const items = res.data?.data?.items || []; - const total = res.data?.data?.total || 0; - all.push(...items); - if (all.length >= total || items.length === 0) break; - query.page_no += 1; - } - return all; + return fetchAllPages({ + pageSize: 9999, + initialQuery: query, + fetchPage: async (q) => { + const res = await DemoAPI.getDemoList( + normalizeDemoQuery(q as unknown as Record) + ); + return { + total: res.data?.data?.total ?? 0, + list: res.data?.data?.items ?? [], + }; + }, + }); }, -} as unknown as IContentConfig; -// 详情表单 -const detailFormData = ref({}); -// 日期范围临时变量 -const createdDateRange = ref<[Date, Date] | []>([]); -// 更新时间范围临时变量 -const updatedDateRange = ref<[Date, Date] | []>([]); - -// 处理创建时间范围变化 -function handleCreatedDateRangeChange(range: [Date, Date]) { - createdDateRange.value = range; - if (range && range.length === 2) { - queryFormData.created_time = [formatToDateTime(range[0]), formatToDateTime(range[1])]; - } else { - queryFormData.created_time = undefined; - } -} - -// 处理更新时间范围变化 -function handleUpdatedDateRangeChange(range: [Date, Date]) { - updatedDateRange.value = range; - if (range && range.length === 2) { - queryFormData.updated_time = [formatToDateTime(range[0]), formatToDateTime(range[1])]; - } else { - queryFormData.updated_time = undefined; - } -} - -// 分页查询参数 -const queryFormData = reactive({ - page_no: 1, - page_size: 10, - name: undefined, - status: undefined, - created_time: undefined, - updated_time: undefined, - created_id: undefined, - updated_id: undefined, }); -// 编辑表单 +const detailFormData = ref({}); + const formData = reactive({ id: undefined, name: "", @@ -773,79 +641,29 @@ const formData = reactive({ i: undefined, }); -// 弹窗状态 const dialogVisible = reactive({ title: "", visible: false, type: "create" as "create" | "update" | "detail", }); -// 表单验证规则 const rules = reactive({ name: [{ required: true, message: "请输入名称", trigger: "blur" }], status: [{ required: true, message: "请选择状态", trigger: "blur" }], }); -// 导入弹窗显示状态 -const importDialogVisible = ref(false); -const uploadLoading = ref(false); +const dataFormRef = ref(); -// 导出弹窗显示状态 -const exportsDialogVisible = ref(false); +const metadataList = ref<{ key: string; value: string }[]>([]); -// 打开导入弹窗 -function handleOpenImportDialog() { - importDialogVisible.value = true; +function handleToggleSearch() { + searchRef.value?.toggleVisible(); } -// 打开导出弹窗 -function handleOpenExportsModal() { - exportsDialogVisible.value = true; +function handleRowDelete(id: number) { + contentRef.value?.handleDelete(id); } -// 列表刷新 -async function handleRefresh() { - await loadingData(); -} - -// 加载表格数据 -async function loadingData() { - loading.value = true; - try { - const response = await DemoAPI.getDemoList(queryFormData); - pageTableData.value = response.data.data.items; - total.value = response.data.data.total; - } catch (error: any) { - console.error(error); - } finally { - loading.value = false; - } -} - -// 查询(重置页码后获取数据) -async function handleQuery() { - queryFormData.page_no = 1; - loadingData(); -} - -// 选择创建人后触发查询 -function handleConfirm() { - handleQuery(); -} - -// 重置查询 -async function handleResetQuery() { - queryFormRef.value.resetFields(); - queryFormData.page_no = 1; - // 重置日期范围选择器 - createdDateRange.value = []; - updatedDateRange.value = []; - queryFormData.created_time = undefined; - queryFormData.updated_time = undefined; - loadingData(); -} - -// 定义初始表单数据常量 const initialFormData: DemoForm = { id: undefined, name: "", @@ -862,30 +680,20 @@ const initialFormData: DemoForm = { i: undefined, }; -// 重置表单 async function resetForm() { if (dataFormRef.value) { dataFormRef.value.resetFields(); dataFormRef.value.clearValidate(); } - // 完全重置 formData 为初始状态 Object.assign(formData, initialFormData); metadataList.value = []; } -// 行复选框选中项变化 -async function handleSelectionChange(selection: any) { - selectIds.value = selection.map((item: any) => item.id); - selectionRows.value = selection; -} - -// 关闭弹窗 async function handleCloseDialog() { dialogVisible.visible = false; resetForm(); } -// 打开弹窗 async function handleOpenDialog(type: "create" | "update" | "detail", id?: number) { dialogVisible.type = type; if (id) { @@ -913,12 +721,9 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe dialogVisible.visible = true; } -// 提交表单(防抖) async function handleSubmit() { - // 表单校验 - dataFormRef.value.validate(async (valid: any) => { + dataFormRef.value.validate(async (valid: boolean) => { if (valid) { - loading.value = true; const submitData = { ...formData }; if (metadataList.value.length > 0) { const metadataObj: Record = {}; @@ -932,51 +737,37 @@ async function handleSubmit() { submitData.i = undefined; } const id = formData.id; - if (id) { - try { + try { + if (id) { await DemoAPI.updateDemo(id, { id, ...submitData }); - dialogVisible.visible = false; - resetForm(); - handleCloseDialog(); - handleResetQuery(); - } catch (error: any) { - console.error(error); - } finally { - loading.value = false; - } - } else { - try { + } else { await DemoAPI.createDemo(submitData); - dialogVisible.visible = false; - resetForm(); - handleCloseDialog(); - handleResetQuery(); - } catch (error: any) { - console.error(error); - } finally { - loading.value = false; } + dialogVisible.visible = false; + await resetForm(); + refreshList(); + } catch (error: unknown) { + console.error(error); } } }); } -// 删除、批量删除 -async function handleDelete(ids: number[]) { - ElMessageBox.confirm("确认删除该项数据?", "警告", { +async function handleMoreClick(status: string) { + const rows = contentRef.value?.getSelectionData() ?? []; + const ids = rows.map((r: { id?: number }) => r.id).filter(Boolean) as number[]; + if (!ids.length) return; + ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", { confirmButtonText: "确定", cancelButtonText: "取消", type: "warning", }) .then(async () => { try { - loading.value = true; - await DemoAPI.deleteDemo(ids); - handleResetQuery(); - } catch (error: any) { + await DemoAPI.batchDemo({ ids, status }); + refreshList(); + } catch (error: unknown) { console.error(error); - } finally { - loading.value = false; } }) .catch(() => { @@ -984,50 +775,8 @@ async function handleDelete(ids: number[]) { }); } -// 批量启用/停用 -async function handleMoreClick(status: string) { - if (selectIds.value.length) { - ElMessageBox.confirm(`确认${status === "0" ? "启用" : "停用"}该项数据?`, "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning", - }) - .then(async () => { - try { - loading.value = true; - await DemoAPI.batchDemo({ ids: selectIds.value, status }); - handleResetQuery(); - } catch (error: any) { - console.error(error); - } finally { - loading.value = false; - } - }) - .catch(() => { - ElMessageBox.close(); - }); - } -} - -// 处理上传 -const handleUpload = async (formData: FormData) => { - try { - uploadLoading.value = true; - const response = await DemoAPI.importDemo(formData); - if (response.data.code === ResultEnum.SUCCESS) { - ElMessage.success(`${response.data.msg},${response.data.data}`); - importDialogVisible.value = false; - await handleQuery(); - } - } catch (error: any) { - console.error(error); - } finally { - uploadLoading.value = false; - } -}; - onMounted(() => { - loadingData(); + refreshList(); }); diff --git a/frontend/src/views/module_generator/gencode/index.vue b/frontend/src/views/module_generator/gencode/index.vue index 67a4e4b0..7b862a78 100644 --- a/frontend/src/views/module_generator/gencode/index.vue +++ b/frontend/src/views/module_generator/gencode/index.vue @@ -1,57 +1,15 @@ - + - @@ -825,7 +761,7 @@ 写入本地 - + @@ -838,7 +774,7 @@ defineOptions({ import "codemirror/mode/javascript/javascript.js"; import "codemirror/mode/sql/sql.js"; import "codemirror/theme/dracula.css"; -import { ref, reactive, computed, onActivated, onMounted, watch } from "vue"; +import { ref, reactive, computed, onActivated, watch, nextTick, unref } from "vue"; import { useClipboard } from "@vueuse/core"; import { useRoute } from "vue-router"; import Codemirror from "codemirror-editor-vue3"; @@ -866,6 +802,14 @@ import { formatTree } from "@/utils/common"; import { MenuTypeEnum } from "@/enums"; import { useSettingsStore } from "@/store"; import { ThemeMode } from "@/enums/settings/theme.enum"; +import CrudToolbarLeft from "@/components/CURD/CrudToolbarLeft.vue"; +import CrudToolbarRight from "@/components/CURD/CrudToolbarRight.vue"; +import PageSearch from "@/components/CURD/PageSearch.vue"; +import PageContent from "@/components/CURD/PageContent.vue"; +import EnhancedDialog from "@/components/CURD/EnhancedDialog.vue"; +import EnhancedDrawer from "@/components/CURD/EnhancedDrawer.vue"; +import { useCrudList } from "@/components/CURD/useCrudList"; +import type { IContentConfig, ISearchConfig } from "@/components/CURD/types"; // 表格列配置接口 interface TableColumn { @@ -890,8 +834,10 @@ interface FileData { content: string; } +const { searchRef, contentRef, handleQueryClick, handleResetClick, refreshList } = useCrudList(); + // 组件引用 -const queryRef = ref(); +const importQueryRef = ref(); const table = ref(); const cmRef = ref(); const sqlRef = ref(); @@ -900,7 +846,6 @@ const basicInfo = ref(); // 状态管理 const loading = ref(false); const nextStepLoading = ref(false); -const total = ref(0); const uniqueId = ref(""); const editVisible = ref(false); const activeStep = ref(2); @@ -911,8 +856,6 @@ const importVisible = ref(false); // 表单和列表数据 const createContent = ref(""); -const dateRange = ref<[Date, Date] | []>([]); -const tableList = ref([]); const dbTableList = ref([]); const ids = ref([]); const tableNames = ref([]); @@ -958,16 +901,31 @@ const previewTypes = ref([...previewTypeOptions]); const code = ref(""); const treeData = ref([]); -// 分页查询参数 -const queryFormData = reactive({ - page_no: 1, - page_size: 10, - table_name: undefined, - table_comment: undefined, +const searchConfig = reactive({ + permPrefix: "module_generator:gencode", + colon: true, + isExpandable: false, + showNumber: 3, + form: { labelWidth: "auto" }, + searchButtonPerm: "module_generator:gencode:query", + resetButtonPerm: "module_generator:gencode:query", + formItems: [ + { + prop: "table_name", + label: "表名称", + type: "input", + attrs: { placeholder: "请输入表名称", clearable: true, style: { width: "200px" } }, + }, + { + prop: "table_comment", + label: "表描述", + type: "input", + attrs: { placeholder: "请输入表描述", clearable: true, style: { width: "200px" } }, + }, + ], }); -// 表格列配置 -const tableColumns = ref([ +const contentCols = reactive([ { prop: "selection", label: "选择框", show: true }, { prop: "index", label: "序号", show: true }, { prop: "table_name", label: "表名称", show: true }, @@ -978,6 +936,26 @@ const tableColumns = ref([ { prop: "operation", label: "操作", show: true }, ]); +const contentConfig = reactive>({ + permPrefix: "module_generator:gencode", + cols: contentCols as IContentConfig["cols"], + hideColumnFilter: false, + toolbar: [], + defaultToolbar: ["refresh", "filter"], + pagination: { + pageSize: 10, + pageSizes: [10, 20, 30, 50], + }, + request: { page_no: "page_no", page_size: "page_size" }, + indexAction: async (params) => { + const res = await GencodeAPI.listTable(params as GenTablePageQuery); + return { + total: res.data.data.total, + list: res.data.data.items, + }; + }, +}); + const settingsStore = useSettingsStore(); // 主题计算属性 @@ -1070,9 +1048,6 @@ const filteredTreeData = computed(() => { return filtered; }); -// 按钮状态计算 -const canGenerate = computed(() => ids.value.length > 0); - // ===== 功能函数 ===== /** 一键复制代码 */ @@ -1194,22 +1169,6 @@ async function handlePreview(row: GenTableSchema): Promise { } } -/** 查询表集合 */ -async function loadingData(): Promise { - loading.value = true; - try { - const response = await GencodeAPI.listTable(queryFormData); - if (response?.data?.data) { - tableList.value = response.data.data.items; - total.value = response.data.data.total; - } - } catch (error) { - console.error("获取表数据失败:", error); - } finally { - loading.value = false; - } -} - /** 表格行内生成代码操作 */ async function handleGenTable(targetGenType: string, row?: GenTableSchema): Promise { let tbNames: string | string[] = []; @@ -1272,7 +1231,7 @@ async function handleSynchDb(row: GenTableSchema): Promise { loading.value = true; await GencodeAPI.syncDb(tableName); - loadingData(); // 同步成功后刷新列表 + refreshList(); } catch (error) { if (error !== "cancel") { console.error("同步表结构失败:", error); @@ -1282,17 +1241,6 @@ async function handleSynchDb(row: GenTableSchema): Promise { } } -/** 重置按钮操作 */ -async function handleRefresh() { - dateRange.value = []; - // 手动重置表单 - queryFormData.page_no = 1; - queryFormData.page_size = 10; - queryFormData.table_name = undefined; - queryFormData.table_comment = undefined; - await loadingData(); -} - /** 多选框选中数据 - 主表格 */ function handleTableSelectionChange(selection: GenTableSchema[]): void { ids.value = selection.map((item) => item.id!); @@ -1353,15 +1301,12 @@ async function handleDelete(row?: GenTableSchema): Promise { type: "warning", }); - loading.value = true; await GencodeAPI.deleteTable(tableIds); - loadingData(); + refreshList(); } catch (error) { if (error !== "cancel") { console.error("删除表数据失败:", error); } - } finally { - loading.value = false; } } @@ -1432,7 +1377,7 @@ async function handleCreateTable(sql: string): Promise { await GencodeAPI.createTable(sql); createTableVisible.value = false; createContent.value = ""; - loadingData(); + refreshList(); // 创建成功后自动打开导入弹窗 importVisible.value = true; await getDbList(); @@ -1462,14 +1407,12 @@ async function handleImportTable(): Promise { const tableNames = tables.value.map((table) => table.table_name || ""); await GencodeAPI.importTable(tableNames); importVisible.value = false; - loadingData(); // 导入成功后刷新已导入的表列表 + refreshList(); // 导入成功后自动打开代码生成抽屉 if (tables.value.length === 1) { - // 只导入了一个表,刷新列表后自动打开该表的代码生成 - await loadingData(); - const importedTable = tableList.value.find( - (t) => t.table_name === tables.value[0].table_name - ); + await nextTick(); + const list = (unref(contentRef.value?.pageData) ?? []) as GenTableSchema[]; + const importedTable = list.find((t) => t.table_name === tables.value[0].table_name); if (importedTable) { await handlePreviewTable(importedTable); } @@ -1513,18 +1456,10 @@ async function handleImportQuery(): Promise { /** 导入弹窗重置按钮操作 */ async function handleImportReset(): Promise { - if (queryRef.value) { - queryRef.value.resetFields(); - } + importQueryRef.value?.resetFields(); await handleImportQuery(); } -/** 搜索按钮操作 */ -async function handleQuery(): Promise { - queryFormData.page_no = 1; - await loadingData(); -} - // 路由和导航 const route = useRoute(); @@ -1535,9 +1470,14 @@ onActivated(async () => { const time = route.query.t; if (time != null && String(time) !== uniqueId.value) { uniqueId.value = String(time); - queryFormData.page_no = Number(route.query.page_no || 1); - dateRange.value = []; - await loadingData(); + const pageNo = Number(route.query.page_no || 1); + await nextTick(); + if (contentRef.value) { + contentRef.value.pagination.currentPage = pageNo; + const q = searchRef.value?.getQueryParams() ?? {}; + const f = contentRef.value.getFilterParams?.() ?? {}; + contentRef.value.fetchPageData({ ...q, ...f }, false); + } } }); @@ -1708,14 +1648,6 @@ async function loadTableDetail(id: number | string) { loading.value = false; } } - -// ===== 生命周期函数 - -/** 组件挂载时 */ -onMounted(() => { - // 初始化数据加载 - loadingData(); -}); diff --git a/frontend/src/views/module_monitor/cache/index.vue b/frontend/src/views/module_monitor/cache/index.vue index 726b1691..3769857a 100644 --- a/frontend/src/views/module_monitor/cache/index.vue +++ b/frontend/src/views/module_monitor/cache/index.vue @@ -1,315 +1,324 @@