From 01d3e1ad28aa47d23a7cab165e85eb1787023345 Mon Sep 17 00:00:00 2001 From: "meilin.huang" <954537473@qq.com> Date: Wed, 17 Apr 2024 21:28:28 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E6=95=B0=E6=8D=AE=E5=BA=93?= =?UTF-8?q?=E5=AE=9E=E4=BE=8B=E4=B8=8E=E5=87=AD=E8=AF=81=E5=85=B3=E8=81=94?= =?UTF-8?q?=E8=87=B3=E6=A0=87=E7=AD=BE&=E5=85=B6=E4=BB=96=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E4=BF=AE=E5=A4=8D=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 +- mayfly_go_web/src/common/commonEnum.ts | 20 +- mayfly_go_web/src/common/config.ts | 2 +- mayfly_go_web/src/common/pattern.ts | 6 +- mayfly_go_web/src/hooks/usePageTable.ts | 1 + mayfly_go_web/src/router/dynamicRouter.ts | 2 +- .../views/ops/component/ResourceAuthCert.vue | 2 +- .../ops/component/ResourceAuthCertEdit.vue | 14 +- .../src/views/ops/component/ResourceTags.vue | 20 +- .../src/views/ops/component/TagTreeSelect.vue | 10 +- mayfly_go_web/src/views/ops/component/tag.ts | 26 ++ mayfly_go_web/src/views/ops/db/DbEdit.vue | 142 +++---- mayfly_go_web/src/views/ops/db/DbList.vue | 107 ++---- .../src/views/ops/db/InstanceDbConf.vue | 171 +++++++++ .../src/views/ops/db/InstanceEdit.vue | 121 +++--- .../src/views/ops/db/InstanceList.vue | 51 ++- mayfly_go_web/src/views/ops/db/SqlExec.vue | 2 +- mayfly_go_web/src/views/ops/db/api.ts | 2 +- .../db/component/sqleditor/DbSqlEditor.vue | 10 +- .../ops/db/component/table/DbTableData.vue | 5 +- .../ops/db/component/table/DbTablesOp.vue | 2 +- .../src/views/ops/machine/MachineEdit.vue | 37 +- .../src/views/ops/mongo/MongoEdit.vue | 29 +- .../src/views/ops/mongo/MongoList.vue | 2 +- .../src/views/ops/redis/RedisEdit.vue | 29 +- .../src/views/ops/tag/AuthCertList.vue | 3 +- .../src/views/ops/tag/TagTreeList.vue | 17 +- mayfly_go_web/src/views/ops/tag/TeamList.vue | 84 +++-- .../src/views/system/account/AccountEdit.vue | 14 +- .../src/views/system/config/ConfigEdit.vue | 10 +- .../views/system/resource/ResourceEdit.vue | 12 +- .../src/views/system/role/RoleEdit.vue | 10 +- server/internal/db/api/dashbord.go | 7 +- server/internal/db/api/db.go | 8 +- server/internal/db/api/db_instance.go | 41 +- server/internal/db/api/form/db.go | 17 +- server/internal/db/api/form/instance.go | 12 +- server/internal/db/api/vo/instance.go | 1 + server/internal/db/application/db.go | 68 ++-- .../internal/db/application/db_data_sync.go | 2 +- server/internal/db/application/db_instance.go | 106 +++++- server/internal/db/application/db_sql_exec.go | 2 +- server/internal/db/application/db_transfer.go | 2 +- server/internal/db/dbm/dbi/conn.go | 25 +- server/internal/db/domain/entity/query.go | 10 +- .../db/infrastructure/persistence/instance.go | 3 +- server/internal/db/router/instance.go | 2 +- server/internal/machine/api/dashbord.go | 14 +- server/internal/machine/api/form/form.go | 4 +- server/internal/machine/api/machine.go | 18 +- .../internal/machine/application/machine.go | 83 +++-- server/internal/mongo/api/form/mongo.go | 4 +- server/internal/mongo/api/mongo.go | 2 +- server/internal/mongo/application/mongo.go | 30 +- server/internal/redis/api/form/redis.go | 2 +- server/internal/redis/api/redis.go | 7 +- server/internal/redis/application/redis.go | 37 +- server/internal/tag/api/form/tag.go | 9 + server/internal/tag/api/tag_tree.go | 19 +- server/internal/tag/api/vo/tag_tree.go | 42 +-- .../tag/application/resouce_auth_cert.go | 84 ++--- server/internal/tag/application/tag_tree.go | 350 ++++++++++-------- server/internal/tag/domain/entity/query.go | 1 - .../tag/domain/entity/resource_auth_cert.go | 10 - server/internal/tag/domain/entity/tag_tree.go | 88 ++++- .../infrastructure/persistence/tag_tree.go | 6 +- server/pkg/config/app.go | 2 +- server/resources/script/sql/v1.8/v1.8.1.sql | 145 ++++++++ 68 files changed, 1421 insertions(+), 809 deletions(-) create mode 100644 mayfly_go_web/src/views/ops/db/InstanceDbConf.vue create mode 100644 server/internal/tag/api/form/tag.go create mode 100644 server/resources/script/sql/v1.8/v1.8.1.sql diff --git a/mayfly_go_web/package.json b/mayfly_go_web/package.json index 3c7e538a..a44deb51 100644 --- a/mayfly_go_web/package.json +++ b/mayfly_go_web/package.json @@ -34,7 +34,7 @@ "sql-formatter": "^15.0.2", "trzsz": "^1.1.5", "uuid": "^9.0.1", - "vue": "^3.4.21", + "vue": "^3.4.23", "vue-router": "^4.3.0", "xterm": "^5.3.0", "xterm-addon-fit": "^0.8.0", @@ -57,7 +57,7 @@ "prettier": "^3.2.5", "sass": "^1.69.0", "typescript": "^5.3.2", - "vite": "^5.2.8", + "vite": "^5.2.9", "vue-eslint-parser": "^9.4.2" }, "browserslist": [ diff --git a/mayfly_go_web/src/common/commonEnum.ts b/mayfly_go_web/src/common/commonEnum.ts index d450a529..ed948ed6 100644 --- a/mayfly_go_web/src/common/commonEnum.ts +++ b/mayfly_go_web/src/common/commonEnum.ts @@ -1,14 +1,24 @@ import EnumValue from './Enum'; +// 资源类型 +export const ResourceTypeEnum = { + Machine: EnumValue.of(1, '机器').setExtra({ icon: 'Monitor', iconColor: 'var(--el-color-primary)' }).tagTypeSuccess(), + Db: EnumValue.of(2, '数据库实例').setExtra({ icon: 'Coin', iconColor: 'var(--el-color-warning)' }).tagTypeWarning(), + Redis: EnumValue.of(3, 'redis').setExtra({ icon: 'iconfont icon-redis', iconColor: 'var(--el-color-danger)' }).tagTypeInfo(), + Mongo: EnumValue.of(4, 'mongo').setExtra({ icon: 'iconfont icon-mongo', iconColor: 'var(--el-color-success)' }).tagTypeDanger(), +}; + // 标签关联的资源类型 export const TagResourceTypeEnum = { AuthCert: EnumValue.of(-2, '公共凭证').setExtra({ icon: 'Ticket' }), Tag: EnumValue.of(-1, '标签').setExtra({ icon: 'CollectionTag' }), - Machine: EnumValue.of(1, '机器').setExtra({ icon: 'Monitor' }).tagTypeSuccess(), - Db: EnumValue.of(2, '数据库').setExtra({ icon: 'Coin' }).tagTypeWarning(), - Redis: EnumValue.of(3, 'redis').setExtra({ icon: 'iconfont icon-redis' }).tagTypeInfo(), - Mongo: EnumValue.of(4, 'mongo').setExtra({ icon: 'iconfont icon-mongo' }).tagTypeDanger(), + Machine: ResourceTypeEnum.Machine, + Db: ResourceTypeEnum.Db, + Redis: ResourceTypeEnum.Redis, + Mongo: ResourceTypeEnum.Mongo, - MachineAuthCert: EnumValue.of(11, '机器-授权凭证').setExtra({ icon: 'Ticket' }), + MachineAuthCert: EnumValue.of(11, '机器-授权凭证').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }), + DbAuthCert: EnumValue.of(21, '数据库-授权凭证').setExtra({ icon: 'Ticket', iconColor: 'var(--el-color-success)' }), + DbName: EnumValue.of(22, '数据库').setExtra({ icon: 'Coin' }), }; diff --git a/mayfly_go_web/src/common/config.ts b/mayfly_go_web/src/common/config.ts index 21ff8131..312e90e1 100644 --- a/mayfly_go_web/src/common/config.ts +++ b/mayfly_go_web/src/common/config.ts @@ -15,7 +15,7 @@ const config = { baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`, // 系统版本 - version: 'v1.8.0', + version: 'v1.8.1', }; export default config; diff --git a/mayfly_go_web/src/common/pattern.ts b/mayfly_go_web/src/common/pattern.ts index 274a7763..4b394792 100644 --- a/mayfly_go_web/src/common/pattern.ts +++ b/mayfly_go_web/src/common/pattern.ts @@ -1,9 +1,9 @@ export const AccountUsernamePattern = { pattern: /^[a-zA-Z0-9_]{5,20}$/g, - message: '只允许输入5-20位大小写字母、数字、下划线', + message: '只允许输入5-20位大小写字母、数字、_-.:', }; export const ResourceCodePattern = { - pattern: /^[a-zA-Z0-9_.:]{1,32}$/g, - message: '只允许输入1-32位大小写字母、数字、_.:', + pattern: /^[a-zA-Z0-9_\-.:]{1,32}$/g, + message: '只允许输入1-32位大小写字母、数字、_-.:', }; diff --git a/mayfly_go_web/src/hooks/usePageTable.ts b/mayfly_go_web/src/hooks/usePageTable.ts index 5ed5083d..beba5b20 100644 --- a/mayfly_go_web/src/hooks/usePageTable.ts +++ b/mayfly_go_web/src/hooks/usePageTable.ts @@ -44,6 +44,7 @@ export const usePageTable = ( } let res = await api.request(sp); + res.list = res.list || []; dataCallBack && (res = await dataCallBack(res)); if (pageable) { diff --git a/mayfly_go_web/src/router/dynamicRouter.ts b/mayfly_go_web/src/router/dynamicRouter.ts index 3cd43a38..441f6d7b 100644 --- a/mayfly_go_web/src/router/dynamicRouter.ts +++ b/mayfly_go_web/src/router/dynamicRouter.ts @@ -159,6 +159,6 @@ export function dynamicImport(dynamicViewsModules: Record, com return null; } - console.error(`未匹配到[${component}]组件名对应的组件文件`); + console.warn(`未匹配到[${component}]组件名对应的组件文件`); return null; } diff --git a/mayfly_go_web/src/views/ops/component/ResourceAuthCert.vue b/mayfly_go_web/src/views/ops/component/ResourceAuthCert.vue index 58e7eb56..88f13d79 100644 --- a/mayfly_go_web/src/views/ops/component/ResourceAuthCert.vue +++ b/mayfly_go_web/src/views/ops/component/ResourceAuthCert.vue @@ -1,6 +1,6 @@ diff --git a/mayfly_go_web/src/views/ops/component/TagTreeSelect.vue b/mayfly_go_web/src/views/ops/component/TagTreeSelect.vue index 846d1f56..10707707 100644 --- a/mayfly_go_web/src/views/ops/component/TagTreeSelect.vue +++ b/mayfly_go_web/src/views/ops/component/TagTreeSelect.vue @@ -4,15 +4,14 @@ v-bind="$attrs" v-model="state.selectTags" @change="changeTag" - style="width: 100%" :data="tags" placeholder="请选择关联标签" :render-after-expand="true" :default-expanded-keys="[state.selectTags]" show-checkbox - node-key="id" + node-key="codePath" :props="{ - value: 'id', + value: 'codePath', label: 'codePath', children: 'children', }" @@ -35,6 +34,7 @@ + diff --git a/mayfly_go_web/src/views/ops/db/InstanceEdit.vue b/mayfly_go_web/src/views/ops/db/InstanceEdit.vue index fd2c62b5..b0f293bb 100644 --- a/mayfly_go_web/src/views/ops/db/InstanceEdit.vue +++ b/mayfly_go_web/src/views/ops/db/InstanceEdit.vue @@ -7,9 +7,30 @@ 基本 - - + + + + + + + + @@ -34,7 +55,7 @@ - + : @@ -87,18 +108,7 @@ 其他 - - - + @@ -107,17 +117,15 @@ diff --git a/mayfly_go_web/src/views/ops/db/InstanceList.vue b/mayfly_go_web/src/views/ops/db/InstanceList.vue index 4cc4ece0..231003be 100644 --- a/mayfly_go_web/src/views/ops/db/InstanceList.vue +++ b/mayfly_go_web/src/views/ops/db/InstanceList.vue @@ -9,6 +9,7 @@ :show-selection="true" v-model:selection-data="state.selectionData" :columns="columns" + lazy > + + @@ -30,6 +35,7 @@ @@ -56,11 +62,13 @@ + + @@ -76,17 +84,30 @@ import SvgIcon from '@/components/svgIcon/index.vue'; import { getDbDialect } from './dialect'; import { SearchItem } from '@/components/SearchForm'; import ResourceAuthCert from '../component/ResourceAuthCert.vue'; +import ResourceTags from '../component/ResourceTags.vue'; +import { getTagPathSearchItem } from '../component/tag'; +import { TagResourceTypeEnum } from '@/common/commonEnum'; const InstanceEdit = defineAsyncComponent(() => import('./InstanceEdit.vue')); +const InstanceDbConf = defineAsyncComponent(() => import('./InstanceDbConf.vue')); + +const props = defineProps({ + lazy: { + type: [Boolean], + default: false, + }, +}); const perms = { saveInstance: 'db:instance:save', delInstance: 'db:instance:del', + saveDb: 'db:save', }; -const searchItems = [SearchItem.input('code', '编号'), SearchItem.input('name', '名称')]; +const searchItems = [getTagPathSearchItem(TagResourceTypeEnum.Db.value), SearchItem.input('code', '编号'), SearchItem.input('name', '名称')]; const columns = ref([ + TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20), TableColumn.new('name', '名称'), TableColumn.new('type', '类型').isSlot().setAddWidth(-15).alignCenter(), TableColumn.new('host', 'host:port').setFormatFunc((data: any) => `${data.host}:${data.port}`), @@ -98,7 +119,7 @@ const columns = ref([ // 该用户拥有的的操作列按钮权限 const actionBtns = hasPerms(Object.values(perms)); -const actionColumn = TableColumn.new('action', '操作').isSlot().setMinWidth(110).fixedRight().alignCenter(); +const actionColumn = TableColumn.new('action', '操作').isSlot().setMinWidth(180).fixedRight().alignCenter(); const pageTableRef: Ref = ref(null); const state = reactive({ @@ -114,6 +135,7 @@ const state = reactive({ */ query: { name: null, + tagPath: '', pageNum: 1, pageSize: 0, }, @@ -126,17 +148,28 @@ const state = reactive({ data: null as any, title: '新增数据库实例', }, + dbEditDialog: { + visible: false, + instance: null as any, + title: '新增数据库实例', + }, }); -const { selectionData, query, infoDialog, instanceEditDialog } = toRefs(state); +const { selectionData, query, infoDialog, instanceEditDialog, dbEditDialog } = toRefs(state); onMounted(async () => { if (Object.keys(actionBtns).length > 0) { columns.value.push(actionColumn); } + if (!props.lazy) { + search(); + } }); -const search = () => { +const search = (tagPath: string = '') => { + if (tagPath) { + state.query.tagPath = tagPath; + } pageTableRef.value.search(); }; @@ -179,5 +212,13 @@ const deleteInstance = async () => { // } }; + +const editDb = (data: any) => { + state.dbEditDialog.instance = data; + state.dbEditDialog.title = `配置 "${data.name}" 数据库`; + state.dbEditDialog.visible = true; +}; + +defineExpose({ search }); diff --git a/mayfly_go_web/src/views/ops/db/SqlExec.vue b/mayfly_go_web/src/views/ops/db/SqlExec.vue index 8ac4387c..c0e6c1b5 100644 --- a/mayfly_go_web/src/views/ops/db/SqlExec.vue +++ b/mayfly_go_web/src/views/ops/db/SqlExec.vue @@ -2,7 +2,7 @@
- +