mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 07:50:25 +08:00
fix: some issue
This commit is contained in:
@@ -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"
|
||||
},
|
||||
|
||||
32
frontend/src/views/ops/component/ResourceOpPanel.vue
Normal file
32
frontend/src/views/ops/component/ResourceOpPanel.vue
Normal 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>
|
||||
@@ -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'));
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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'));
|
||||
|
||||
|
||||
@@ -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'));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user