From fc166650b39c66fc98b381a5e30afaec4ccc3338 Mon Sep 17 00:00:00 2001 From: "meilin.huang" <954537473@qq.com> Date: Tue, 26 Mar 2024 21:46:03 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20dbm=E9=87=8D=E6=9E=84=E7=AD=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mayfly_go_web/package.json | 4 +- .../src/views/ops/component/TagTree.vue | 4 +- mayfly_go_web/src/views/ops/db/DbList.vue | 24 +- mayfly_go_web/src/views/ops/db/SqlExec.vue | 5 +- .../src/views/ops/tag/TagTreeList.vue | 4 +- mayfly_go_web/src/views/system/enums.ts | 2 +- .../views/system/resource/ResourceList.vue | 231 +++++++++--------- server/internal/db/api/db.go | 150 ++---------- server/internal/db/application/db.go | 127 ++++++++++ .../internal/db/application/db_data_sync.go | 10 +- server/internal/db/application/db_transfer.go | 12 +- .../db/{api => application}/gzip_writer.go | 2 +- server/internal/db/application/param.go | 13 + server/internal/db/dbm/dbi/dialect.go | 18 +- server/internal/db/dbm/dbi/metadata.go | 10 +- server/internal/db/dbm/dbi/metadata_base.go | 66 ++++- server/internal/db/dbm/dm/dialect.go | 27 +- server/internal/db/dbm/dm/helper.go | 222 +++++++++++++++++ server/internal/db/dbm/dm/metadata.go | 192 +-------------- server/internal/db/dbm/mssql/dialect.go | 25 -- server/internal/db/dbm/mssql/helper.go | 225 +++++++++++++++++ server/internal/db/dbm/mssql/metadata.go | 194 +-------------- server/internal/db/dbm/mysql/dialect.go | 28 --- server/internal/db/dbm/mysql/helper.go | 202 +++++++++++++++ server/internal/db/dbm/mysql/metadata.go | 179 +------------- server/internal/db/dbm/oracle/dialect.go | 27 -- server/internal/db/dbm/oracle/helper.go | 179 ++++++++++++++ server/internal/db/dbm/oracle/metadata.go | 150 +----------- server/internal/db/dbm/postgres/dialect.go | 26 -- server/internal/db/dbm/postgres/helper.go | 229 +++++++++++++++++ server/internal/db/dbm/postgres/metadata.go | 184 +------------- server/internal/db/dbm/sqlite/dialect.go | 26 -- server/internal/db/dbm/sqlite/helper.go | 184 ++++++++++++++ server/internal/db/dbm/sqlite/metadata.go | 156 +----------- 34 files changed, 1660 insertions(+), 1477 deletions(-) rename server/internal/db/{api => application}/gzip_writer.go (97%) create mode 100644 server/internal/db/application/param.go create mode 100644 server/internal/db/dbm/dm/helper.go create mode 100644 server/internal/db/dbm/mssql/helper.go create mode 100644 server/internal/db/dbm/mysql/helper.go create mode 100644 server/internal/db/dbm/oracle/helper.go create mode 100644 server/internal/db/dbm/postgres/helper.go create mode 100644 server/internal/db/dbm/sqlite/helper.go diff --git a/mayfly_go_web/package.json b/mayfly_go_web/package.json index 63b1e19a..00a89e13 100644 --- a/mayfly_go_web/package.json +++ b/mayfly_go_web/package.json @@ -17,7 +17,7 @@ "countup.js": "^2.8.0", "cropperjs": "^1.6.1", "echarts": "^5.5.0", - "element-plus": "^2.6.1", + "element-plus": "^2.6.2", "js-base64": "^3.7.7", "jsencrypt": "^3.3.2", "lodash": "^4.17.21", @@ -56,7 +56,7 @@ "prettier": "^3.2.5", "sass": "^1.69.0", "typescript": "^5.3.2", - "vite": "^5.2.2", + "vite": "^5.2.6", "vue-eslint-parser": "^9.4.2" }, "browserslist": [ diff --git a/mayfly_go_web/src/views/ops/component/TagTree.vue b/mayfly_go_web/src/views/ops/component/TagTree.vue index 5345e661..1dd82915 100644 --- a/mayfly_go_web/src/views/ops/component/TagTree.vue +++ b/mayfly_go_web/src/views/ops/component/TagTree.vue @@ -10,7 +10,7 @@ :props="treeProps" lazy node-key="key" - :expand-on-click-node="true" + :expand-on-click-node="false" :filter-node-method="filterNode" @node-click="treeNodeClick" @node-expand="treeNodeClick" @@ -140,8 +140,8 @@ const loadNode = async (node: any, resolve: any) => { }; const treeNodeClick = (data: any) => { - emit('nodeClick', data); if (!data.disabled && !data.type.nodeDblclickFunc && data.type.nodeClickFunc) { + emit('nodeClick', data); data.type.nodeClickFunc(data); } // 关闭可能存在的右击菜单 diff --git a/mayfly_go_web/src/views/ops/db/DbList.vue b/mayfly_go_web/src/views/ops/db/DbList.vue index a6d4a5da..fb2455b4 100644 --- a/mayfly_go_web/src/views/ops/db/DbList.vue +++ b/mayfly_go_web/src/views/ops/db/DbList.vue @@ -89,8 +89,8 @@ - - + + @@ -220,6 +220,7 @@ import DbBackupList from './DbBackupList.vue'; import DbBackupHistoryList from './DbBackupHistoryList.vue'; import DbRestoreList from './DbRestoreList.vue'; import ResourceTags from '../component/ResourceTags.vue'; +import { sleep } from '@/common/utils/loading'; const DbEdit = defineAsyncComponent(() => import('./DbEdit.vue')); @@ -499,9 +500,8 @@ const onDumpDbs = async (row: any) => { /** * 数据库信息导出 */ -const dumpDbs = () => { +const dumpDbs = async () => { isTrue(state.exportDialog.value.length > 0, '请添加要导出的数据库'); - const a = document.createElement('a'); let type = 0; for (let c of state.exportDialog.contents) { if (c == '结构') { @@ -510,13 +510,15 @@ const dumpDbs = () => { type += 2; } } - a.setAttribute( - 'href', - `${config.baseApiUrl}/dbs/${state.exportDialog.dbId}/dump?db=${state.exportDialog.value.join(',')}&type=${type}&extName=${ - state.exportDialog.extName - }&${joinClientParams()}` - ); - a.click(); + for (let db of state.exportDialog.value) { + const a = document.createElement('a'); + a.setAttribute( + 'href', + `${config.baseApiUrl}/dbs/${state.exportDialog.dbId}/dump?db=${db}&type=${type}&extName=${state.exportDialog.extName}&${joinClientParams()}` + ); + a.click(); + await sleep(500); + } state.exportDialog.visible = false; }; diff --git a/mayfly_go_web/src/views/ops/db/SqlExec.vue b/mayfly_go_web/src/views/ops/db/SqlExec.vue index 7bc81b1f..d1e06505 100644 --- a/mayfly_go_web/src/views/ops/db/SqlExec.vue +++ b/mayfly_go_web/src/views/ops/db/SqlExec.vue @@ -366,7 +366,10 @@ const NodeTypeTableMenu = new NodeType(SqlExecNodeType.TableMenu) parentNode.params.dbTableSize = dbTableSize == 0 ? '' : formatByteSize(dbTableSize); return tablesNode; }) - .withNodeClickFunc(nodeClickChangeDb); + .withNodeDblclickFunc((node: TagTreeNode) => { + const params = node.params; + addTablesOpTab({ id: params.id, db: params.db, type: params.type, nodeKey: node.key }); + }); // 数据库sql模板菜单节点 const NodeTypeSqlMenu = new NodeType(SqlExecNodeType.SqlMenu) diff --git a/mayfly_go_web/src/views/ops/tag/TagTreeList.vue b/mayfly_go_web/src/views/ops/tag/TagTreeList.vue index 1ffb22f0..b169756a 100644 --- a/mayfly_go_web/src/views/ops/tag/TagTreeList.vue +++ b/mayfly_go_web/src/views/ops/tag/TagTreeList.vue @@ -30,7 +30,7 @@ ref="tagTreeRef" class="none-select" node-key="id" - :highlight-current="true" + highlight-current :props="props" :data="data" @node-expand="handleNodeExpand" @@ -193,7 +193,7 @@ const state = reactive({ }, items: [contextmenuEdit, contextmenuAdd, contextmenuDel], }, - activeTabName: 'tagDetail', + activeTabName: TagDetail, currentTag: null as any, resourceCount: {} as any, }); diff --git a/mayfly_go_web/src/views/system/enums.ts b/mayfly_go_web/src/views/system/enums.ts index 1fc7e185..c3835121 100644 --- a/mayfly_go_web/src/views/system/enums.ts +++ b/mayfly_go_web/src/views/system/enums.ts @@ -1,7 +1,7 @@ import { EnumValue } from '@/common/Enum'; export const ResourceTypeEnum = { - Menu: EnumValue.of(1, '菜单'), + Menu: EnumValue.of(1, '菜单').tagTypeSuccess(), Permission: EnumValue.of(2, '权限'), }; diff --git a/mayfly_go_web/src/views/system/resource/ResourceList.vue b/mayfly_go_web/src/views/system/resource/ResourceList.vue index 0226bdc1..6fbe9437 100644 --- a/mayfly_go_web/src/views/system/resource/ResourceList.vue +++ b/mayfly_go_web/src/views/system/resource/ResourceList.vue @@ -1,52 +1,103 @@ @@ -108,8 +120,9 @@ import ResourceEdit from './ResourceEdit.vue'; import { ResourceTypeEnum } from '../enums'; import { resourceApi } from '../api'; import { dateFormat } from '@/common/utils/date'; -import EnumValue from '@/common/Enum'; +import EnumTag from '@/components/enumtag/EnumTag.vue'; import { Contextmenu, ContextmenuItem } from '@/components/contextmenu'; +import { Splitpanes, Pane } from 'splitpanes'; const menuTypeValue = ResourceTypeEnum.Menu.value; const permissionTypeValue = ResourceTypeEnum.Permission.value; @@ -130,7 +143,7 @@ const contextmenuRef = ref(); const filterResource = ref(); const resourceTreeRef = ref(); -const contextmenuInfo = new ContextmenuItem('info', '详情').withIcon('View').withOnClick((data: any) => info(data)); +const ResourceDetail = 'resourceDetail'; const contextmenuAdd = new ContextmenuItem('add', '添加子资源') .withIcon('circle-plus') @@ -166,7 +179,7 @@ const state = reactive({ x: 0, y: 0, }, - items: [contextmenuInfo, contextmenuAdd, contextmenuEdit, contextmenuEnable, contextmenuDisable, contextmenuDel], + items: [contextmenuAdd, contextmenuEdit, contextmenuEnable, contextmenuDisable, contextmenuDel], }, //弹出框对象 dialogForm: { @@ -177,29 +190,15 @@ const state = reactive({ // 资源类型选择是否选 typeDisabled: true, }, - //资源信息弹出框对象 - infoDialog: { - title: '', - visible: false, - // 资源类型选择是否选 - data: { - meta: {} as any, - name: '', - type: null, - creator: '', - modifier: '', - createTime: '', - updateTime: '', - code: '', - }, - }, data: [], // 展开的节点 defaultExpandedKeys: [] as any[], + activeTabName: ResourceDetail, + currentResource: null as any, }); -const { dialogForm, infoDialog, data, defaultExpandedKeys } = toRefs(state); +const { currentResource, dialogForm, data, defaultExpandedKeys } = toRefs(state); onMounted(() => { search(); @@ -229,9 +228,15 @@ const nodeContextmenu = (event: any, data: any) => { contextmenuRef.value.openContextmenu(data); }; -const treeNodeClick = () => { +const treeNodeClick = async (data: any) => { // 关闭可能存在的右击菜单 contextmenuRef.value.closeContextmenu(); + + let info = await resourceApi.detail.request({ id: data.id }); + state.currentResource = info; + if (info.meta && info.meta != '') { + state.currentResource.meta = JSON.parse(info.meta); + } }; const deleteMenu = (data: any) => { @@ -390,15 +395,6 @@ const removeDeafultExpandId = (id: any) => { state.defaultExpandedKeys.splice(index, 1); } }; - -const info = async (data: any) => { - let info = await resourceApi.detail.request({ id: data.id }); - state.infoDialog.data = info; - if (info.meta && info.meta != '') { - state.infoDialog.data.meta = JSON.parse(info.meta); - } - state.infoDialog.visible = true; -};