mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 23:40:24 +08:00
refactor: 界面优化
This commit is contained in:
File diff suppressed because one or more lines are too long
135
mayfly_go_web/src/components/contextmenu/index.vue
Normal file
135
mayfly_go_web/src/components/contextmenu/index.vue
Normal file
@@ -0,0 +1,135 @@
|
||||
<template>
|
||||
<transition name="el-zoom-in-center">
|
||||
<div aria-hidden="true" class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu" role="tooltip"
|
||||
data-popper-placement="bottom" :style="`top: ${dropdowns.y + 5}px;left: ${dropdowns.x}px;`" :key="Math.random()"
|
||||
v-show="state.isShow">
|
||||
<ul class="el-dropdown-menu">
|
||||
<template v-for="(v, k) in state.dropdownList">
|
||||
<li class="el-dropdown-menu__item" aria-disabled="false" tabindex="-1" :key="k" v-if="!v.affix"
|
||||
@click="onCurrentContextmenuClick(v.contextMenuClickId)">
|
||||
<SvgIcon :name="v.icon" />
|
||||
<span>{{ v.txt }}</span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<div class="el-popper__arrow" :style="{ left: `${state.arrowLeft}px` }"></div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="layoutTagsViewContextmenu">
|
||||
import { computed, reactive, onMounted, onUnmounted, watch } from 'vue';
|
||||
|
||||
// 定义父组件传过来的值
|
||||
const props = defineProps({
|
||||
dropdown: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
},
|
||||
},
|
||||
items: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
});
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['currentContextmenuClick']);
|
||||
|
||||
// 定义变量内容
|
||||
const state = reactive({
|
||||
isShow: false,
|
||||
dropdownList: [
|
||||
{ contextMenuClickId: 0, txt: '刷新', affix: false, icon: 'RefreshRight' },
|
||||
{ contextMenuClickId: 1, txt: '关闭', affix: false, icon: 'Close' },
|
||||
{ contextMenuClickId: 2, txt: '关闭其他', affix: false, icon: 'CircleClose' },
|
||||
{ contextMenuClickId: 3, txt: '关闭所有', affix: false, icon: 'FolderDelete' },
|
||||
],
|
||||
item: {} as any,
|
||||
arrowLeft: 10,
|
||||
});
|
||||
|
||||
// 父级传过来的坐标 x,y 值
|
||||
const dropdowns = computed(() => {
|
||||
// 117 为 `Dropdown 下拉菜单` 的宽度
|
||||
if (props.dropdown.x + 117 > document.documentElement.clientWidth) {
|
||||
return {
|
||||
x: document.documentElement.clientWidth - 117 - 5,
|
||||
y: props.dropdown.y,
|
||||
};
|
||||
} else {
|
||||
return props.dropdown;
|
||||
}
|
||||
});
|
||||
// 当前项菜单点击
|
||||
const onCurrentContextmenuClick = (contextMenuClickId: number) => {
|
||||
emit('currentContextmenuClick', { id: contextMenuClickId, item: state.item });
|
||||
};
|
||||
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
|
||||
const openContextmenu = (item: any) => {
|
||||
state.item = item;
|
||||
closeContextmenu();
|
||||
setTimeout(() => {
|
||||
state.isShow = true;
|
||||
}, 10);
|
||||
};
|
||||
// 关闭右键菜单
|
||||
const closeContextmenu = () => {
|
||||
state.isShow = false;
|
||||
};
|
||||
// 监听页面监听进行右键菜单的关闭
|
||||
onMounted(() => {
|
||||
document.body.addEventListener('click', closeContextmenu);
|
||||
});
|
||||
// 页面卸载时,移除右键菜单监听事件
|
||||
onUnmounted(() => {
|
||||
document.body.removeEventListener('click', closeContextmenu);
|
||||
});
|
||||
// 监听下拉菜单位置
|
||||
watch(
|
||||
() => props.dropdown,
|
||||
({ x }) => {
|
||||
if (x + 117 > document.documentElement.clientWidth) state.arrowLeft = 117 - (document.documentElement.clientWidth - x);
|
||||
else state.arrowLeft = 10;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
watch(
|
||||
() => props.items,
|
||||
(x: any) => {
|
||||
state.dropdownList = x
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openContextmenu,
|
||||
closeContextmenu,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-contextmenu {
|
||||
transform-origin: center top;
|
||||
z-index: 2190;
|
||||
position: fixed;
|
||||
|
||||
.el-dropdown-menu__item {
|
||||
font-size: 12px !important;
|
||||
white-space: nowrap;
|
||||
|
||||
i {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,110 +1,138 @@
|
||||
<template>
|
||||
<transition name="el-zoom-in-center">
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu"
|
||||
role="tooltip"
|
||||
data-popper-placement="bottom"
|
||||
:style="`top: ${dropdowns.y + 5}px;left: ${dropdowns.x}px;`"
|
||||
:key="Math.random()"
|
||||
v-show="isShow"
|
||||
>
|
||||
<ul class="el-dropdown-menu">
|
||||
<template v-for="(v, k) in dropdownList">
|
||||
<li
|
||||
class="el-dropdown-menu__item"
|
||||
aria-disabled="false"
|
||||
tabindex="-1"
|
||||
:key="k"
|
||||
v-if="!v.affix"
|
||||
@click="onCurrentContextmenuClick(v.id)"
|
||||
>
|
||||
<i :class="v.icon"></i>
|
||||
<span>{{ v.txt }}</span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<div class="el-popper__arrow" style="left: 10px"></div>
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="el-zoom-in-center">
|
||||
<div
|
||||
aria-hidden="true"
|
||||
class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu"
|
||||
role="tooltip"
|
||||
data-popper-placement="bottom"
|
||||
:style="`top: ${dropdowns.y + 5}px;left: ${dropdowns.x}px;`"
|
||||
:key="Math.random()"
|
||||
v-show="state.isShow"
|
||||
>
|
||||
<ul class="el-dropdown-menu">
|
||||
<template v-for="(v, k) in state.dropdownList">
|
||||
<li
|
||||
class="el-dropdown-menu__item"
|
||||
aria-disabled="false"
|
||||
tabindex="-1"
|
||||
:key="k"
|
||||
v-if="!v.affix"
|
||||
@click="onCurrentContextmenuClick(v.contextMenuClickId)"
|
||||
>
|
||||
<SvgIcon :name="v.icon" />
|
||||
<span>{{ v.txt }}</span>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<div class="el-popper__arrow" :style="{ left: `${state.arrowLeft}px` }"></div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent, reactive, toRefs, onMounted, onUnmounted } from 'vue';
|
||||
export default defineComponent({
|
||||
name: 'layoutTagsViewContextmenu',
|
||||
props: {
|
||||
dropdown: {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
setup(props, { emit }) {
|
||||
const state = reactive({
|
||||
isShow: false,
|
||||
dropdownList: [
|
||||
{ id: 0, txt: '刷新', affix: false, icon: 'el-icon-refresh-right' },
|
||||
{ id: 1, txt: '关闭', affix: false, icon: 'el-icon-close' },
|
||||
{ id: 2, txt: '关闭其他', affix: false, icon: 'el-icon-circle-close' },
|
||||
{ id: 3, txt: '关闭所有', affix: false, icon: 'el-icon-folder-delete' },
|
||||
{
|
||||
id: 4,
|
||||
txt: '当前页全屏',
|
||||
affix: false,
|
||||
icon: 'el-icon-full-screen',
|
||||
},
|
||||
],
|
||||
path: {},
|
||||
});
|
||||
// 父级传过来的坐标 x,y 值
|
||||
const dropdowns = computed(() => {
|
||||
return props.dropdown;
|
||||
});
|
||||
// 当前项菜单点击
|
||||
const onCurrentContextmenuClick = (id: number) => {
|
||||
emit('currentContextmenuClick', { id, path: state.path });
|
||||
};
|
||||
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
|
||||
const openContextmenu = (item: any) => {
|
||||
state.path = item.fullPath;
|
||||
item.meta.isAffix ? (state.dropdownList[1].affix = true) : (state.dropdownList[1].affix = false);
|
||||
closeContextmenu();
|
||||
setTimeout(() => {
|
||||
state.isShow = true;
|
||||
}, 10);
|
||||
};
|
||||
// 关闭右键菜单
|
||||
const closeContextmenu = () => {
|
||||
state.isShow = false;
|
||||
};
|
||||
// 监听页面监听进行右键菜单的关闭
|
||||
onMounted(() => {
|
||||
document.body.addEventListener('click', closeContextmenu);
|
||||
});
|
||||
// 页面卸载时,移除右键菜单监听事件
|
||||
onUnmounted(() => {
|
||||
document.body.removeEventListener('click', closeContextmenu);
|
||||
});
|
||||
return {
|
||||
dropdowns,
|
||||
openContextmenu,
|
||||
closeContextmenu,
|
||||
onCurrentContextmenuClick,
|
||||
...toRefs(state),
|
||||
};
|
||||
},
|
||||
<script setup lang="ts" name="layoutTagsViewContextmenu">
|
||||
import { computed, reactive, onMounted, onUnmounted, watch } from 'vue';
|
||||
|
||||
// 定义父组件传过来的值
|
||||
const props = defineProps({
|
||||
dropdown: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
x: 0,
|
||||
y: 0,
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// 定义子组件向父组件传值/事件
|
||||
const emit = defineEmits(['currentContextmenuClick']);
|
||||
|
||||
// 定义变量内容
|
||||
const state = reactive({
|
||||
isShow: false,
|
||||
dropdownList: [
|
||||
{ contextMenuClickId: 0, txt: '刷新', affix: false, icon: 'RefreshRight' },
|
||||
{ contextMenuClickId: 1, txt: '关闭', affix: false, icon: 'Close' },
|
||||
{ contextMenuClickId: 2, txt: '关闭其他', affix: false, icon: 'CircleClose' },
|
||||
{ contextMenuClickId: 3, txt: '关闭所有', affix: false, icon: 'FolderDelete' },
|
||||
{
|
||||
contextMenuClickId: 4,
|
||||
txt: '当前页全屏',
|
||||
affix: false,
|
||||
icon: 'full-screen',
|
||||
},
|
||||
],
|
||||
item: {} as any,
|
||||
arrowLeft: 10,
|
||||
});
|
||||
|
||||
// 父级传过来的坐标 x,y 值
|
||||
const dropdowns = computed(() => {
|
||||
// 117 为 `Dropdown 下拉菜单` 的宽度
|
||||
if (props.dropdown.x + 117 > document.documentElement.clientWidth) {
|
||||
return {
|
||||
x: document.documentElement.clientWidth - 117 - 5,
|
||||
y: props.dropdown.y,
|
||||
};
|
||||
} else {
|
||||
return props.dropdown;
|
||||
}
|
||||
});
|
||||
// 当前项菜单点击
|
||||
const onCurrentContextmenuClick = (contextMenuClickId: number) => {
|
||||
emit('currentContextmenuClick', { id: contextMenuClickId, path: state.item.fullPath });
|
||||
};
|
||||
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
|
||||
const openContextmenu = (item: any) => {
|
||||
state.item = item;
|
||||
item.meta?.isAffix ? (state.dropdownList[1].affix = true) : (state.dropdownList[1].affix = false);
|
||||
closeContextmenu();
|
||||
setTimeout(() => {
|
||||
state.isShow = true;
|
||||
}, 10);
|
||||
};
|
||||
// 关闭右键菜单
|
||||
const closeContextmenu = () => {
|
||||
state.isShow = false;
|
||||
};
|
||||
// 监听页面监听进行右键菜单的关闭
|
||||
onMounted(() => {
|
||||
document.body.addEventListener('click', closeContextmenu);
|
||||
});
|
||||
// 页面卸载时,移除右键菜单监听事件
|
||||
onUnmounted(() => {
|
||||
document.body.removeEventListener('click', closeContextmenu);
|
||||
});
|
||||
// 监听下拉菜单位置
|
||||
watch(
|
||||
() => props.dropdown,
|
||||
({ x }) => {
|
||||
if (x + 117 > document.documentElement.clientWidth) state.arrowLeft = 117 - (document.documentElement.clientWidth - x);
|
||||
else state.arrowLeft = 10;
|
||||
},
|
||||
{
|
||||
deep: true,
|
||||
}
|
||||
);
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
openContextmenu,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.custom-contextmenu {
|
||||
transform-origin: center top;
|
||||
z-index: 2190;
|
||||
position: fixed;
|
||||
.el-dropdown-menu__item {
|
||||
font-size: 12px !important;
|
||||
i {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
transform-origin: center top;
|
||||
z-index: 2190;
|
||||
position: fixed;
|
||||
.el-dropdown-menu__item {
|
||||
font-size: 12px !important;
|
||||
white-space: nowrap;
|
||||
i {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -9,8 +9,8 @@
|
||||
if (el) tagsRefs[k] = el;
|
||||
}
|
||||
">
|
||||
<i class="iconfont icon-webicon318 layout-navbars-tagsview-ul-li-iconfont font14"
|
||||
v-if="isActive(v)"></i>
|
||||
<SvgIcon name="iconfont icon-tag-view-active" class="layout-navbars-tagsview-ul-li-iconfont font14"
|
||||
v-if="isActive(v)" />
|
||||
<SvgIcon :name="v.meta.icon" class="layout-navbars-tagsview-ul-li-iconfont"
|
||||
v-if="!isActive(v) && themeConfig.isTagsviewIcon" />
|
||||
<span>{{ v.meta.title }}</span>
|
||||
@@ -82,7 +82,7 @@ const initTagsView = () => {
|
||||
state.tagsViewList = getSession('tagsViewList');
|
||||
} else {
|
||||
state.tagsViews?.map((v: any) => {
|
||||
if (v.meta.isAffix && !v.meta.isHide) state.tagsViewList.push({ ...v });
|
||||
if (v.meta.isAffix && !v.meta.isHide) state.tagsViewList.push({ ...v });
|
||||
});
|
||||
addTagsView(route.fullPath);
|
||||
}
|
||||
@@ -523,4 +523,5 @@ onBeforeRouteUpdate((to) => {
|
||||
|
||||
.layout-navbars-tagsview-shadow {
|
||||
box-shadow: rgb(0 21 41 / 4%) 0px 1px 4px;
|
||||
}</style>
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="instances-box layout-aside">
|
||||
<div class="instances-box">
|
||||
<el-row type="flex" justify="space-between">
|
||||
<el-col :span="24" class="el-scrollbar flex-auto" style="overflow: auto">
|
||||
<el-input v-model="filterText" placeholder="输入关键字->搜索已展开节点信息" clearable size="small" class="mb5" />
|
||||
@@ -7,7 +7,7 @@
|
||||
<el-tree ref="treeRef" :style="{ maxHeight: state.height, height: state.height, overflow: 'auto' }"
|
||||
:highlight-current="true" :indent="7" :load="loadNode" :props="treeProps" lazy node-key="key"
|
||||
:expand-on-click-node="true" :filter-node-method="filterNode" @node-click="treeNodeClick"
|
||||
@node-expand="treeNodeClick">
|
||||
@node-expand="treeNodeClick" @node-contextmenu="nodeContextmenu">
|
||||
<template #default="{ node, data }">
|
||||
<span>
|
||||
<span v-if="data.type == TagTreeNode.TagPath">
|
||||
@@ -19,16 +19,13 @@
|
||||
<span class="ml3">
|
||||
<slot name="label" :data="data"> {{ data.label }}</slot>
|
||||
</span>
|
||||
|
||||
<span class="ml3">
|
||||
<slot name="option" :data="data"></slot>
|
||||
</span>
|
||||
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<contextmenu :dropdown="state.dropdown" :items="state.contextmenuItems" ref="contextmenuRef"
|
||||
@currentContextmenuClick="onCurrentContextmenuClick" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -36,6 +33,7 @@
|
||||
import { onMounted, reactive, ref, watch, toRefs } from 'vue';
|
||||
import { TagTreeNode } from './tag';
|
||||
import TagInfo from './TagInfo.vue';
|
||||
import Contextmenu from '@/components/contextmenu/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
height: {
|
||||
@@ -45,6 +43,10 @@ const props = defineProps({
|
||||
load: {
|
||||
type: Function,
|
||||
required: true,
|
||||
},
|
||||
loadContextmenuItems: {
|
||||
type: Function,
|
||||
required: false,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -54,12 +56,18 @@ const treeProps = {
|
||||
isLeaf: 'isLeaf',
|
||||
}
|
||||
|
||||
const emit = defineEmits(['nodeClick'])
|
||||
const emit = defineEmits(['nodeClick', 'currentContextmenuClick'])
|
||||
const treeRef: any = ref(null)
|
||||
const contextmenuRef = ref();
|
||||
|
||||
const state = reactive({
|
||||
height: 600 as any,
|
||||
filterText: '',
|
||||
dropdown: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
contextmenuItems: [],
|
||||
opend: {},
|
||||
})
|
||||
const { filterText } = toRefs(state)
|
||||
@@ -101,6 +109,29 @@ const loadNode = async (node: any, resolve: any) => {
|
||||
|
||||
const treeNodeClick = (data: any) => {
|
||||
emit('nodeClick', data);
|
||||
// 关闭可能存在的右击菜单
|
||||
contextmenuRef.value.closeContextmenu();
|
||||
}
|
||||
|
||||
// 树节点右击事件
|
||||
const nodeContextmenu = (event: any, data: any) => {
|
||||
if (!props.loadContextmenuItems) {
|
||||
return;
|
||||
}
|
||||
// 加载当前节点是否需要显示右击菜单
|
||||
const items = props.loadContextmenuItems(data)
|
||||
if (!items || items.length == 0) {
|
||||
return;
|
||||
}
|
||||
state.contextmenuItems = items;
|
||||
const { clientX, clientY } = event;
|
||||
state.dropdown.x = clientX;
|
||||
state.dropdown.y = clientY;
|
||||
contextmenuRef.value.openContextmenu(data);
|
||||
}
|
||||
|
||||
const onCurrentContextmenuClick = (clickData: any) => {
|
||||
emit('currentContextmenuClick', clickData);
|
||||
}
|
||||
|
||||
const reloadNode = (nodeKey: any) => {
|
||||
@@ -125,6 +156,7 @@ defineExpose({
|
||||
<style lang="scss">
|
||||
.instances-box {
|
||||
overflow: 'auto';
|
||||
position: relative;
|
||||
|
||||
.el-tree {
|
||||
display: inline-block;
|
||||
|
||||
@@ -23,13 +23,15 @@
|
||||
</el-row>
|
||||
<el-row type="flex">
|
||||
<el-col :span="4" style="border-left: 1px solid #eee; margin-top: 10px">
|
||||
<tag-tree ref="tagTreeRef" @node-click="nodeClick" :load="loadNode" :height="state.tagTreeHeight">
|
||||
<tag-tree ref="tagTreeRef" @node-click="nodeClick" :load="loadNode" :load-contextmenu-items="getContextmenuItems" @current-contextmenu-click="onCurrentContextmenuClick"
|
||||
:height="state.tagTreeHeight">
|
||||
<template #prefix="{ data }">
|
||||
<span v-if="data.type == NodeType.DbInst">
|
||||
<el-popover placement="right-start" title="数据库实例信息" trigger="hover" :width="210">
|
||||
<template #reference>
|
||||
<SvgIcon v-if="data.params.type === 'mysql'" name="iconfont icon-op-mysql" :size="18" />
|
||||
<SvgIcon v-if="data.params.type === 'postgres'" name="iconfont icon-op-postgres" :size="18" />
|
||||
<SvgIcon v-if="data.params.type === 'postgres'" name="iconfont icon-op-postgres"
|
||||
:size="18" />
|
||||
|
||||
<SvgIcon name="InfoFilled" v-else />
|
||||
</template>
|
||||
@@ -54,15 +56,11 @@
|
||||
|
||||
<el-tooltip v-if="data.type == NodeType.Table" effect="customized"
|
||||
:content="data.params.tableComment" placement="top-end">
|
||||
<SvgIcon name="Calendar" color="#409eff" />
|
||||
<SvgIcon name="Calendar" color="#409eff" />
|
||||
</el-tooltip>
|
||||
|
||||
<SvgIcon name="Files" v-if="data.type == NodeType.SqlMenu || data.type == NodeType.Sql" color="#f56c6c" />
|
||||
</template>
|
||||
<template #option="{data}">
|
||||
<span v-if="data.type == NodeType.TableMenu">
|
||||
<el-link @click="reloadTables(data.key)" icon="refresh" :underline="false"></el-link>
|
||||
</span>
|
||||
<SvgIcon name="Files" v-if="data.type == NodeType.SqlMenu || data.type == NodeType.Sql"
|
||||
color="#f56c6c" />
|
||||
</template>
|
||||
</tag-tree>
|
||||
</el-col>
|
||||
@@ -119,6 +117,9 @@ class NodeType {
|
||||
static Table = 5;
|
||||
static Sql = 6;
|
||||
}
|
||||
class ContextmenuClickId {
|
||||
static ReloadTable = 0
|
||||
}
|
||||
|
||||
const tagTreeRef: any = ref(null)
|
||||
|
||||
@@ -134,7 +135,7 @@ const state = reactive({
|
||||
tabs,
|
||||
dataTabsTableHeight: '600',
|
||||
editorHeight: '600',
|
||||
tagTreeHeight: window.innerHeight - 178 + 'px',
|
||||
tagTreeHeight: window.innerHeight - 173 + 'px',
|
||||
genSqlDialog: {
|
||||
visible: false,
|
||||
sql: '',
|
||||
@@ -171,9 +172,9 @@ const getInsts = async () => {
|
||||
if (!res.total) return
|
||||
for (const db of res.list) {
|
||||
const tagPath = db.tagPath;
|
||||
let redisInsts = instMap.get(tagPath) || [];
|
||||
redisInsts.push(db);
|
||||
instMap.set(tagPath, redisInsts);
|
||||
let dbInsts = instMap.get(tagPath) || [];
|
||||
dbInsts.push(db);
|
||||
instMap.set(tagPath, dbInsts?.sort());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,10 +262,28 @@ const nodeClick = async (data: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getContextmenuItems = (data: any) => {
|
||||
const dataType = data.type;
|
||||
if (dataType === NodeType.TableMenu) {
|
||||
return [
|
||||
{ contextMenuClickId: ContextmenuClickId.ReloadTable, txt: '刷新', icon: 'RefreshRight' }
|
||||
]
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
// 当前右击菜单点击事件
|
||||
const onCurrentContextmenuClick = (clickData: any) => {
|
||||
const clickId = clickData.id;
|
||||
if (clickId == ContextmenuClickId.ReloadTable) {
|
||||
reloadTables(clickData.item.key)
|
||||
}
|
||||
}
|
||||
|
||||
const getTables = async (params: any) => {
|
||||
const { id, db } = params;
|
||||
let tables = await DbInst.getInst(id).loadTables(db, state.reloadStatus);
|
||||
state.reloadStatus=false
|
||||
state.reloadStatus = false
|
||||
return tables.map((x: any) => {
|
||||
return new TagTreeNode(`${id}.${db}.${x.tableName}`, x.tableName, NodeType.Table).withIsLeaf(true).withParams({
|
||||
id,
|
||||
@@ -413,9 +432,9 @@ const getSqlMenuNodeKey = (dbId: number, db: string) => {
|
||||
return `${dbId}.${db}.sql-menu`
|
||||
}
|
||||
|
||||
const reloadTables = (nodeKey:string) => {
|
||||
state.reloadStatus=true
|
||||
tagTreeRef.value.reloadNode(nodeKey);
|
||||
const reloadTables = (nodeKey: string) => {
|
||||
state.reloadStatus = true
|
||||
tagTreeRef.value.reloadNode(nodeKey);
|
||||
}
|
||||
|
||||
const registerSqlCompletionItemProvider = () => {
|
||||
|
||||
@@ -68,6 +68,9 @@ export class DbInst {
|
||||
if (!reload && tables) {
|
||||
return tables;
|
||||
}
|
||||
// 重置列信息缓存与表提示信息
|
||||
db.columnsMap?.clear();
|
||||
db.tableHints = null;
|
||||
console.log(`load tables -> dbName: ${dbName}`);
|
||||
tables = await dbApi.tableMetadata.request({ id: this.id, db: dbName });
|
||||
db.tables = tables;
|
||||
|
||||
Reference in New Issue
Block a user