fix: some issue

This commit is contained in:
meilin.huang
2025-03-11 12:42:20 +08:00
parent c7c3fd7f7e
commit bc21ba7c1e
23 changed files with 280 additions and 242 deletions

View File

@@ -11,7 +11,7 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@vueuse/core": "^12.7.0",
"@vueuse/core": "^12.8.2",
"@xterm/addon-fit": "^0.10.0",
"@xterm/addon-search": "^0.15.0",
"@xterm/addon-web-links": "^0.11.0",
@@ -59,9 +59,9 @@
"eslint": "^8.35.0",
"eslint-plugin-vue": "^9.31.0",
"prettier": "^3.2.5",
"sass": "^1.85.0",
"typescript": "^5.7.3",
"vite": "^6.2.0",
"sass": "^1.85.1",
"typescript": "^5.8.2",
"vite": "^6.2.1",
"vite-plugin-progress": "0.0.7",
"vue-eslint-parser": "^9.4.3"
},

View File

@@ -0,0 +1,32 @@
<template>
<Splitpanes class="default-theme" @resize="handleResize">
<Pane :size="leftPaneSize" max-size="30">
<slot name="left"></slot>
</Pane>
<Pane>
<slot name="right"></slot>
</Pane>
</Splitpanes>
</template>
<script lang="ts" setup>
import { Pane, Splitpanes } from 'splitpanes';
import { useWindowSize } from '@vueuse/core';
import { computed } from 'vue';
const emit = defineEmits(['resize']);
const { width } = useWindowSize();
console.log(width);
const leftPaneSize = computed(() => (width.value >= 1600 ? 20 : 25));
// 处理 resize 事件
const handleResize = (event: any) => {
emit('resize', event);
};
</script>
<style lang="scss"></style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="db-sql-exec">
<Splitpanes class="default-theme">
<Pane size="20" max-size="30">
<ResourceOpPanel>
<template #left>
<tag-tree
:default-expanded-keys="state.defaultExpendKey"
:resource-type="TagResourceTypePath.Db"
@@ -51,9 +51,9 @@
<span v-if="data.type.value == SqlExecNodeType.TableMenu && data.params.dbTableSize">{{ ` ${data.params.dbTableSize}` }}</span>
</template>
</tag-tree>
</Pane>
</template>
<Pane>
<template #right>
<div class="card db-op pd5">
<el-row>
<el-col :span="24" v-if="state.db">
@@ -211,8 +211,9 @@
</el-tabs>
</div>
</div>
</Pane>
</Splitpanes>
</template>
</ResourceOpPanel>
<db-table-op
:title="tableCreateDialog.title"
:active-name="tableCreateDialog.activeName"
@@ -247,7 +248,6 @@ import { Contextmenu, ContextmenuItem } from '@/components/contextmenu';
import { getDbDialect, schemaDbTypes } from './dialect/index';
import { sleep } from '@/common/utils/loading';
import { TagResourceTypeEnum, TagResourceTypePath } from '@/common/commonEnum';
import { Pane, Splitpanes } from 'splitpanes';
import { useEventListener, useStorage } from '@vueuse/core';
import SqlExecBox from '@/views/ops/db/component/sqleditor/SqlExecBox';
import { useAutoOpenResource } from '@/store/autoOpenResource';
@@ -256,6 +256,7 @@ import { format as sqlFormatter } from 'sql-formatter';
import MonacoEditor from '@/components/monaco/MonacoEditor.vue';
import { useI18n } from 'vue-i18n';
import { useI18nCreateTitle, useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nEditTitle, useI18nOperateSuccessMsg } from '@/hooks/useI18n';
import ResourceOpPanel from '../component/ResourceOpPanel.vue';
const DbTableOp = defineAsyncComponent(() => import('./component/table/DbTableOp.vue'));
const DbSqlEditor = defineAsyncComponent(() => import('./component/sqleditor/DbSqlEditor.vue'));

View File

@@ -89,7 +89,7 @@
<el-dialog width="40%" :title="`${chooseTableName} ${$t('db.column')}`" v-model="columnDialog.visible">
<el-table border stripe :data="columnDialog.columns" size="small">
<el-table-column prop="columnName" :label="$t('common.columnName')" show-overflow-tooltip> </el-table-column>
<el-table-column prop="columnName" :label="$t('db.columnName')" show-overflow-tooltip> </el-table-column>
<el-table-column width="120" prop="columnType" :label="$t('common.type')" show-overflow-tooltip> </el-table-column>
<el-table-column width="80" prop="nullable" :label="$t('db.nullable')" show-overflow-tooltip> </el-table-column>
<el-table-column prop="columnComment" :label="$t('db.comment')" show-overflow-tooltip> </el-table-column>

View File

@@ -317,7 +317,7 @@ const searchItems = [
const columns = [
TableColumn.new('tags[0].tagPath', 'tag.relateTag').isSlot('tagPath').setAddWidth(20),
TableColumn.new('name', 'common.name'),
TableColumn.new('ipPort', 'Ip:Port').isSlot().setAddWidth(50),
TableColumn.new('ipPort', 'Ip:Port').isSlot().setAddWidth(55),
TableColumn.new('authCerts[0].username', 'machine.acName').isSlot('authCert').setAddWidth(10),
TableColumn.new('status', 'common.status').isSlot().setAddWidth(5),
TableColumn.new('stat', 'machine.runningStat').isSlot().setAddWidth(55),

View File

@@ -1,8 +1,7 @@
<template>
<div class="flex-all-center">
<!-- 文档 https://antoniandre.github.io/splitpanes/ -->
<Splitpanes class="default-theme" @resized="onResizeTagTree">
<Pane size="20" max-size="30">
<ResourceOpPanel @resized="onResizeTagTree">
<template #left>
<tag-tree
class="machine-terminal-tree"
ref="tagTreeRef"
@@ -30,9 +29,9 @@
}}</span>
</template>
</tag-tree>
</Pane>
</template>
<Pane>
<template #right>
<div class="machine-terminal-tabs card pd5">
<el-tabs v-if="state.tabs.size > 0" type="card" @tab-remove="onRemoveTab" style="width: 100%" v-model="state.activeTermName" class="h100">
<el-tab-pane class="h100" closable v-for="dt in state.tabs.values()" :label="dt.label" :name="dt.key" :key="dt.key">
@@ -157,8 +156,8 @@
<machine-rec v-model:visible="machineRecDialog.visible" :machineId="machineRecDialog.machineId" :title="machineRecDialog.title" />
</div>
</Pane>
</Splitpanes>
</template>
</ResourceOpPanel>
</div>
</template>
@@ -171,7 +170,6 @@ import { hasPerms } from '@/components/auth/auth';
import { TagResourceTypeEnum, TagResourceTypePath } from '@/common/commonEnum';
import { NodeType, TagTreeNode, getTagTypeCodeByPath } from '../component/tag';
import TagTree from '../component/TagTree.vue';
import { Pane, Splitpanes } from 'splitpanes';
import { ContextmenuItem } from '@/components/contextmenu/index';
import TerminalBody from '@/components/terminal/TerminalBody.vue';
import { TerminalStatus, TerminalStatusEnum } from '@/components/terminal/common';
@@ -183,6 +181,7 @@ import { useAutoOpenResource } from '@/store/autoOpenResource';
import { storeToRefs } from 'pinia';
import EnumValue from '@/common/Enum';
import { useI18n } from 'vue-i18n';
import ResourceOpPanel from '../component/ResourceOpPanel.vue';
// 组件
const ScriptManage = defineAsyncComponent(() => import('./ScriptManage.vue'));

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex-all-center">
<Splitpanes class="default-theme">
<Pane size="20" max-size="30">
<ResourceOpPanel>
<template #left>
<tag-tree
ref="tagTreeRef"
:default-expanded-keys="state.defaultExpendKey"
@@ -40,9 +40,9 @@
<span v-if="data.type.value == MongoNodeType.Dbs">{{ formatByteSize(data.params.size) }}</span>
</template>
</tag-tree>
</Pane>
</template>
<Pane>
<template #right>
<div class="mongo-data-tab card pd5 w100">
<el-row v-if="nowColl">
<el-descriptions class="w100" :column="10" size="small" border>
@@ -121,8 +121,8 @@
</el-tabs>
</el-row>
</div>
</Pane>
</Splitpanes>
</template>
</ResourceOpPanel>
<el-dialog width="600px" title="find params" v-model="findDialog.visible">
<el-form label-width="auto">
@@ -177,11 +177,11 @@ import TagTree from '../component/TagTree.vue';
import { formatByteSize } from '@/common/utils/format';
import { TagResourceTypeEnum } from '@/common/commonEnum';
import { sleep } from '@/common/utils/loading';
import { Splitpanes, Pane } from 'splitpanes';
import { useAutoOpenResource } from '@/store/autoOpenResource';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useI18nDeleteSuccessMsg, useI18nSaveSuccessMsg } from '@/hooks/useI18n';
import ResourceOpPanel from '../component/ResourceOpPanel.vue';
const MonacoEditor = defineAsyncComponent(() => import('@/components/monaco/MonacoEditor.vue'));

View File

@@ -1,7 +1,7 @@
<template>
<div class="redis-data-op flex-all-center">
<Splitpanes class="default-theme">
<Pane size="20" max-size="30">
<ResourceOpPanel>
<template #left>
<tag-tree
ref="tagTreeRef"
:default-expanded-keys="state.defaultExpendKey"
@@ -40,122 +40,126 @@
<span v-if="data.type.value == RedisNodeType.Db">{{ data.params.keys }}</span>
</template>
</tag-tree>
</Pane>
</template>
<Pane min-size="20" size="30">
<div class="key-list-vtree card pd5">
<el-scrollbar>
<el-row>
<el-col :span="2">
<el-input v-model="state.keySeparator" :placeholder="$t('redis.delimiter')" size="small" class="ml5" />
</el-col>
<el-col :span="18">
<el-input
@clear="clear"
v-model="scanParam.match"
@keyup.enter.native="searchKey()"
:placeholder="$t('redis.keyMatchTips')"
clearable
size="small"
class="ml10"
/>
</el-col>
<el-col :span="4">
<el-button
class="ml15"
:disabled="!scanParam.id || !scanParam.db"
@click="searchKey()"
type="success"
icon="search"
size="small"
plain
></el-button>
</el-col>
</el-row>
<template #right>
<Splitpanes class="default-theme">
<Pane size="40" max-size="45">
<div class="key-list-vtree card pd5">
<el-scrollbar>
<el-row>
<el-col :span="2">
<el-input v-model="state.keySeparator" :placeholder="$t('redis.delimiter')" size="small" class="ml5" />
</el-col>
<el-col :span="18">
<el-input
@clear="clear"
v-model="scanParam.match"
@keyup.enter.native="searchKey()"
:placeholder="$t('redis.keyMatchTips')"
clearable
size="small"
class="ml10"
/>
</el-col>
<el-col :span="4">
<el-button
class="ml15"
:disabled="!scanParam.id || !scanParam.db"
@click="searchKey()"
type="success"
icon="search"
size="small"
plain
></el-button>
</el-col>
</el-row>
<el-row class="mb5 mt5">
<el-col :span="19">
<el-button
class="ml5"
:disabled="!scanParam.id || !scanParam.db"
@click="scan(true)"
type="success"
icon="more"
size="small"
plain
>{{ $t('redis.loadMore') }}</el-button
<el-row class="mb5 mt5">
<el-col :span="19">
<el-button
class="ml5"
:disabled="!scanParam.id || !scanParam.db"
@click="scan(true)"
type="success"
icon="more"
size="small"
plain
>{{ $t('redis.loadMore') }}</el-button
>
<el-button
v-auth="'redis:data:save'"
:disabled="!scanParam.id || !scanParam.db"
@click="showNewKeyDialog"
type="primary"
icon="plus"
size="small"
plain
>{{ $t('redis.addKey') }}</el-button
>
<el-button
:disabled="!scanParam.id || !scanParam.db"
@click="flushDb"
type="danger"
plain
v-auth="'redis:data:del'"
size="small"
icon="delete"
>flush</el-button
>
</el-col>
<el-col :span="5">
<span style="display: inline-block" class="mt5">keys:{{ state.dbsize }}</span>
</el-col>
</el-row>
<el-tree
ref="keyTreeRef"
:highlight-current="true"
:data="keyTreeData"
:props="treeProps"
:indent="8"
node-key="key"
:auto-expand-parent="false"
:default-expanded-keys="Array.from(state.keyTreeExpanded)"
@node-click="handleKeyTreeNodeClick"
@node-expand="keyTreeNodeExpand"
@node-collapse="keyTreeNodeCollapse"
@node-contextmenu="rightClickNode"
>
<template #default="{ node, data }">
<span class="el-dropdown-link key-list-custom-node" :title="node.label">
<span v-if="data.type == 1">
<SvgIcon :size="15" :name="node.expanded ? 'folder-opened' : 'folder'" />
</span>
<span :class="'ml5 ' + (data.type == 1 ? 'folder-label' : 'key-label')">
{{ node.label }}
</span>
<el-button
v-auth="'redis:data:save'"
:disabled="!scanParam.id || !scanParam.db"
@click="showNewKeyDialog"
type="primary"
icon="plus"
size="small"
plain
>{{ $t('redis.addKey') }}</el-button
>
<span v-if="!node.isLeaf" class="ml5" style="font-weight: bold"> ({{ data.keyCount }}) </span>
</span>
</template>
</el-tree>
</el-scrollbar>
<el-button
:disabled="!scanParam.id || !scanParam.db"
@click="flushDb"
type="danger"
plain
v-auth="'redis:data:del'"
size="small"
icon="delete"
>flush</el-button
>
</el-col>
<el-col :span="5">
<span style="display: inline-block" class="mt5">keys:{{ state.dbsize }}</span>
</el-col>
</el-row>
<contextmenu :dropdown="state.contextmenu.dropdown" :items="state.contextmenu.items" ref="contextmenuRef" />
</div>
</Pane>
<el-tree
ref="keyTreeRef"
:highlight-current="true"
:data="keyTreeData"
:props="treeProps"
:indent="8"
node-key="key"
:auto-expand-parent="false"
:default-expanded-keys="Array.from(state.keyTreeExpanded)"
@node-click="handleKeyTreeNodeClick"
@node-expand="keyTreeNodeExpand"
@node-collapse="keyTreeNodeCollapse"
@node-contextmenu="rightClickNode"
>
<template #default="{ node, data }">
<span class="el-dropdown-link key-list-custom-node" :title="node.label">
<span v-if="data.type == 1">
<SvgIcon :size="15" :name="node.expanded ? 'folder-opened' : 'folder'" />
</span>
<span :class="'ml5 ' + (data.type == 1 ? 'folder-label' : 'key-label')">
{{ node.label }}
</span>
<span v-if="!node.isLeaf" class="ml5" style="font-weight: bold"> ({{ data.keyCount }}) </span>
</span>
</template>
</el-tree>
</el-scrollbar>
<contextmenu :dropdown="state.contextmenu.dropdown" :items="state.contextmenu.items" ref="contextmenuRef" />
</div>
</Pane>
<Pane min-size="40">
<div class="key-detail card pd5">
<el-tabs @tab-remove="removeDataTab" v-model="state.activeName">
<el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" :name="dt.key">
<key-detail :redis="redisInst" :key-info="dt.keyInfo" @change-key="searchKey()" @del-key="delKey" />
</el-tab-pane>
</el-tabs>
</div>
</Pane>
</Splitpanes>
<Pane min-size="40">
<div class="key-detail card pd5">
<el-tabs @tab-remove="removeDataTab" v-model="state.activeName">
<el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" :name="dt.key">
<key-detail :redis="redisInst" :key-info="dt.keyInfo" @change-key="searchKey()" @del-key="delKey" />
</el-tab-pane>
</el-tabs>
</div>
</Pane>
</Splitpanes>
</template>
</ResourceOpPanel>
<div style="text-align: center; margin-top: 10px"></div>
@@ -204,6 +208,7 @@ import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI18nFormValidate, useI18nOperateSuccessMsg } from '@/hooks/useI18n';
import { Rules } from '@/common/rule';
import ResourceOpPanel from '../component/ResourceOpPanel.vue';
const KeyDetail = defineAsyncComponent(() => import('./KeyDetail.vue'));