feat: 代码小调整

This commit is contained in:
meilin.huang
2023-02-07 16:54:44 +08:00
parent fa0cb73ec9
commit 00fee24a85
8 changed files with 528 additions and 592 deletions

View File

@@ -0,0 +1,106 @@
<template>
<div class="instances-box layout-aside">
<el-row type="flex" justify="space-between">
<el-col :span="24"
:style="{ maxHeight: instanceMenuMaxHeight, height: instanceMenuMaxHeight, overflow: 'auto' }"
class="el-scrollbar flex-auto">
<el-menu background-color="transparent" :collapse-transition="false">
<!-- 第一级tag -->
<el-sub-menu v-for="tag of tags" :index="tag.tagPath" :key="tag.tagPath"
@click.stop="clickTag(tag.tagPath)">
<template #title>
<el-icon>
<FolderOpened v-if="opend[tag.tagPath]" color="#e6a23c" />
<Folder v-else />
</el-icon>
<span>{{ tag.tagPath }}</span>
</template>
<slot :tag="tag" name="submenu"></slot>
</el-sub-menu>
</el-menu>
</el-col>
</el-row>
</div>
</template>
<script lang="ts" setup>
import { reactive, toRefs } from 'vue';
const props = defineProps({
instanceMenuMaxHeight: {
type: [Number, String],
},
tags: {
type: Object, required: true
},
})
const state = reactive({
instanceMenuMaxHeight: props.instanceMenuMaxHeight,
tags: props.tags,
opend: {},
})
const {
opend,
} = toRefs(state)
const clickTag = (tagPath: string) => {
if (state.opend[tagPath] === undefined) {
state.opend[tagPath] = true;
return;
}
const opend = state.opend[tagPath]
state.opend[tagPath] = !opend
}
</script>
<style lang="scss">
.instances-box {
.el-menu {
width: 100%;
}
.el-sub-menu {
.checked {
.checked-schema {
color: var(--el-color-primary);
}
}
}
.el-sub-menu__title {
padding-left: 0 !important;
height: 30px !important;
line-height: 30px !important;
}
.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
padding-right: 10px;
}
.el-menu-item {
padding-left: 0 !important;
height: 20px !important;
line-height: 20px !important;
}
.el-icon {
margin: 0;
}
.el-sub-menu__icon-arrow {
top: inherit;
right: 10px;
}
}
.instances-pop-form {
.el-form-item {
margin-bottom: unset;
}
}
</style>

View File

@@ -219,7 +219,8 @@
layout="prev, pager, next, total, jumper" v-model:current-page="dt.pageNum"
:page-size="defalutLimit"></el-pagination>
</el-row>
<div style=" font-size: 12px; padding: 0 10px; color: #606266"><span>{{ dt.sql }}</span></div>
<div style=" font-size: 12px; padding: 0 10px; color: #606266"><span>{{ dt.sql }}</span>
</div>
</el-tab-pane>
</el-tabs>
</el-container>
@@ -258,7 +259,7 @@
</template>
<script lang="ts" setup>
import { computed, nextTick, onMounted, reactive, watch } from 'vue';
import { computed, nextTick, onMounted, reactive } from 'vue';
import { dbApi } from './api';
import { format as sqlFormatter } from 'sql-formatter';
@@ -1754,7 +1755,7 @@ const loadSchemaTables = async (inst: any, schema: string, fn: Function) => {
} else {
tables.forEach((a: any) => a.show = true)
}
fn(state.instances.tables[id+schema])
fn(state.instances.tables[id + schema])
}
// 选择数据库实例

View File

@@ -1,19 +1,9 @@
<template>
<div class="instances-box layout-aside">
<el-row type="flex" justify="space-between">
<el-col :span="24" :style="{maxHeight: instanceMenuMaxHeight,height: instanceMenuMaxHeight, overflow:'auto'}" class="el-scrollbar flex-auto">
<el-menu background-color="transparent" ref="menuRef">
<!-- 第一级tag -->
<el-sub-menu v-for="tag of instances.tags" :index="tag.tagPath" :key="tag.tagPath">
<template #title>
<el-icon>
<FolderOpened color="#e6a23c" />
</el-icon>
<span>{{ tag.tagPath }}</span>
</template>
<tag-menu :instanceMenuMaxHeight="instanceMenuMaxHeight" :tags="instances.tags">
<template #submenu="props">
<!-- 第二级数据库实例 -->
<el-sub-menu v-for="inst in instances.tree[tag.tagId]" :index="'instance-' + inst.id"
:key="'instance-' + inst.id" @click="changeInstance(inst, ()=>{})">
<el-sub-menu v-for="inst in instances.tree[props.tag.tagId]" :index="'instance-' + inst.id"
:key="'instance-' + inst.id" @click.stop="changeInstance(inst, () => { })">
<template #title>
<el-popover placement="right-start" title="数据库实例信息" trigger="hover" :width="210">
<template #reference>
@@ -34,9 +24,9 @@
</el-popover>
</template>
<!-- 第三级数据库 -->
<el-sub-menu v-for="schema in instances.dbs[inst.id]" :index="inst.id + schema"
:key="inst.id + schema" :class="state.nowSchema === (inst.id + schema) && 'checked'"
@click="changeSchema(inst, schema)">
<el-sub-menu v-for="schema in instances.dbs[inst.id]" :index="inst.id + schema" :key="inst.id + schema"
:class="state.nowSchema === (inst.id + schema) && 'checked'"
@click.stop="changeSchema(inst, schema)">
<template #title>
&nbsp;&nbsp;&nbsp;&nbsp;<el-icon>
<Coin color="#67c23a" />
@@ -46,9 +36,9 @@
<!-- 第四级 01 -->
<el-sub-menu :index="inst.id + schema + '-table'">
<template #title>
<div style="width: 100%" @click="loadTableNames(inst, schema, ()=>{})">
<div style="width: 100%" @click="loadTableNames(inst, schema, () => { })">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<el-icon>
<Calendar color="#409eff"/>
<Calendar color="#409eff" />
</el-icon>
<span></span>
<el-icon v-show="state.loading[inst.id + schema]" class="is-loading">
@@ -96,9 +86,8 @@
</template>
<template v-for="sql in instances.sqls[inst.id + schema]">
<el-menu-item :index="inst.id + schema + sql.name"
:key="inst.id + schema + sql.name" v-if="sql.show"
@click="loadSql(inst, schema, sql.name)">
<el-menu-item :index="inst.id + schema + sql.name" :key="inst.id + schema + sql.name"
v-if="sql.show" @click="loadSql(inst, schema, sql.name)">
<template #title>
<div style="width: 100%">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<el-icon>
@@ -112,16 +101,14 @@
</el-sub-menu>
</el-sub-menu>
</el-sub-menu>
</el-sub-menu>
</el-menu>
</el-col>
</el-row>
</div>
</template>
</tag-menu>
</template>
<script lang="ts" setup>
import {nextTick, onBeforeMount, onMounted, reactive, ref, Ref, watch} from 'vue';
import {store} from '@/store';
import { nextTick, onBeforeMount, onMounted, reactive, ref, Ref, watch } from 'vue';
import { store } from '@/store';
import TagMenu from '../../component/TagMenu.vue';
const props = defineProps({
instanceMenuMaxHeight: {
@@ -158,7 +145,7 @@ const initLoadInstances = () => {
* @param inst 选中的实例对象
* @param fn 选中的实例对象后的回调函数
*/
const changeInstance = (inst : any, fn: Function) => {
const changeInstance = (inst: any, fn: Function) => {
emits('changeInstance', inst, fn)
}
/**
@@ -178,7 +165,7 @@ const changeSchema = (inst: any, schema: string) => {
*/
const loadTableNames = async (inst: any, schema: string, fn: Function) => {
state.loading[inst.id + schema] = true
await emits('loadTableNames', inst, schema, (res: any[])=>{
await emits('loadTableNames', inst, schema, (res: any[]) => {
state.loading[inst.id + schema] = false
fn && fn(res)
})
@@ -208,17 +195,17 @@ const filterTableName = (instId: number, schema: string, event?: any) => {
const selectDb = async (val?: any) => {
let info = val || store.state.sqlExecInfo.dbOptInfo;
if (info && info.dbId) {
const {tagPath, dbId, db} = info
const { tagPath, dbId, db } = info
menuRef.value.open(tagPath);
menuRef.value.open('instance-' + dbId);
await changeInstance({id: dbId}, () => {
await changeInstance({ id: dbId }, () => {
// 加载数据库
nextTick(async () => {
menuRef.value.open(dbId + db)
state.nowSchema = (dbId+db)
state.nowSchema = (dbId + db)
// 加载集合列表
await nextTick(async () => {
await loadTableNames({id: dbId}, db, (res: any[]) => {
await loadTableNames({ id: dbId }, db, (res: any[]) => {
// 展开集合列表
menuRef.value.open(dbId + db + '-table')
console.log(res)
@@ -229,11 +216,11 @@ const selectDb = async (val?: any) => {
}
}
onMounted(()=>{
onMounted(() => {
selectDb();
})
watch(()=>store.state.sqlExecInfo.dbOptInfo, async newValue => {
watch(() => store.state.sqlExecInfo.dbOptInfo, async newValue => {
await selectDb(newValue)
})
@@ -241,46 +228,6 @@ watch(()=>store.state.sqlExecInfo.dbOptInfo, async newValue => {
</script>
<style lang="scss">
.instances-box {
.el-menu {
width: 100%;
}
.el-sub-menu {
.checked {
.checked-schema {
color: var(--el-color-primary);
}
}
}
.el-sub-menu__title {
padding-left: 0 !important;
height: 30px !important;
line-height: 30px !important;
}
.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
padding-right: 10px;
}
.el-menu-item {
padding-left: 0 !important;
height: 20px !important;
line-height: 20px !important;
}
.el-icon {
margin: 0;
}
.el-sub-menu__icon-arrow {
top: inherit;
right: 10px;
}
}
.instances-pop-form {
.el-form-item {
margin-bottom: unset;

View File

@@ -1,27 +1,8 @@
<template>
<div class="instances-box layout-aside">
<el-row type="flex" justify="space-between">
<el-col :span="24" :style="{
maxHeight: state.instanceMenuMaxHeight,
height: state.instanceMenuMaxHeight,
overflow: 'auto'
}" class="el-scrollbar flex-auto">
<el-menu background-color="transparent" ref="menuRef">
<!-- 第一级tag -->
<el-sub-menu v-for="tag of instances.tags" :index="tag.tagPath" :key="tag.tagPath">
<template #title>
<el-icon>
<FolderOpened color="#e6a23c" />
</el-icon>
<span>{{ tag.tagPath }}</span>
</template>
<!-- 第二级数据库实例 -->
<el-sub-menu v-for="inst in instances.tree[tag.tagId]"
:index="'mongo-instance-' + inst.id"
:key="'mongo-instance-' + inst.id"
@click.prevent="changeInstance(inst, ()=>{})"
>
<tag-menu :instanceMenuMaxHeight="state.instanceMenuMaxHeight" :tags="instances.tags">
<template #submenu="props">
<el-sub-menu v-for="inst in instances.tree[props.tag.tagId]" :index="'mongo-instance-' + inst.id"
:key="'mongo-instance-' + inst.id" @click.stop="changeInstance(inst, () => { })">
<template #title>
<el-popover placement="right-start" title="mongo数据库实例信息" trigger="hover" :width="210">
<template #reference>
@@ -38,9 +19,9 @@
</el-popover>
</template>
<!-- 第三级数据库 -->
<el-sub-menu v-for="db in instances.dbs[inst.id]" :index="inst.id + db.Name"
:key="inst.id + db.Name" :class="state.nowSchema === (inst.id + db.Name) && 'checked'"
@click.prevent="changeSchema(inst, db.Name)">
<el-sub-menu v-for="db in instances.dbs[inst.id]" :index="inst.id + db.Name" :key="inst.id + db.Name"
:class="state.nowSchema === (inst.id + db.Name) && 'checked'"
@click.stop="changeSchema(inst, db.Name)">
<template #title>
&nbsp;&nbsp;&nbsp;&nbsp;<el-icon>
<Coin color="#67c23a" />
@@ -55,9 +36,9 @@
<!-- 第四级 01 -->
<el-sub-menu :index="inst.id + db.Name + '-table'">
<template #title>
<div style="width: 100%" @click="loadTableNames(inst, db.Name, ()=>{})">
<div style="width: 100%" @click="loadTableNames(inst, db.Name, () => { })">
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<el-icon>
<Calendar color="#409eff"/>
<Calendar color="#409eff" />
</el-icon>
<span>集合</span>
<el-icon v-show="state.loading[inst.id + db.Name]" class="is-loading">
@@ -93,17 +74,15 @@
</el-sub-menu>
</el-sub-menu>
</el-sub-menu>
</el-sub-menu>
</el-menu>
</el-col>
</el-row>
</div>
</template>
</tag-menu>
</template>
<script lang="ts" setup>
import {nextTick, onBeforeMount, onMounted, reactive, ref, Ref, watch} from 'vue';
import { nextTick, onBeforeMount, onMounted, reactive, ref, Ref, watch } from 'vue';
import { formatByteSize } from '@/common/utils/format';
import {store} from '@/store';
import { store } from '@/store';
import TagMenu from '../component/TagMenu.vue';
const props = defineProps({
instances: {
@@ -119,7 +98,7 @@ onBeforeMount(async () => {
})
const setHeight = () => {
state.instanceMenuMaxHeight = window.innerHeight - 140 + 'px';
state.instanceMenuMaxHeight = window.innerHeight - 115 + 'px';
}
const menuRef = ref(null) as Ref
@@ -144,7 +123,7 @@ const initLoadInstances = () => {
* @param inst 选中的实例对象
* @param fn 选中的实例对象后的回调事件
*/
const changeInstance = (inst : any, fn: Function) => {
const changeInstance = (inst: any, fn: Function) => {
emits('changeInstance', inst, fn)
}
/**
@@ -164,7 +143,7 @@ const changeSchema = (inst: any, schema: string) => {
*/
const loadTableNames = async (inst: any, schema: string, fn: Function) => {
state.loading[inst.id + schema] = true
await emits('loadTableNames', inst, schema, (res: any)=>{
await emits('loadTableNames', inst, schema, (res: any) => {
state.loading[inst.id + schema] = false
fn && fn(res)
})
@@ -194,20 +173,20 @@ const filterTableName = (instId: number, schema: string, event?: any) => {
const selectDb = async (val?: any) => {
let info = val || store.state.mongoDbOptInfo.dbOptInfo;
if (info && info.dbId) {
const {tagPath, dbId, db} = info
const { tagPath, dbId, db } = info
menuRef.value.open(tagPath);
menuRef.value.open('mongo-instance-' + dbId);
await changeInstance({id: dbId}, () => {
await changeInstance({ id: dbId }, () => {
// 加载数据库
nextTick(async () => {
menuRef.value.open(dbId + db)
// 加载集合列表
await nextTick(async () => {
await loadTableNames({id: dbId}, db, (res: any[]) => {
await loadTableNames({ id: dbId }, db, (res: any[]) => {
// 展开集合列表
menuRef.value.open(dbId + db + '-table')
// 加载第一张集合数据
loadTableData({id: dbId}, db, res[0].tableName)
loadTableData({ id: dbId }, db, res[0].tableName)
})
})
})
@@ -215,57 +194,17 @@ const selectDb = async (val?: any) => {
}
}
onMounted(()=>{
onMounted(() => {
selectDb();
})
watch(()=>store.state.mongoDbOptInfo.dbOptInfo, async newValue => {
watch(() => store.state.mongoDbOptInfo.dbOptInfo, async newValue => {
await selectDb(newValue)
})
</script>
<style lang="scss">
.instances-box {
.el-menu {
width: 100%;
}
.el-sub-menu {
.checked {
.checked-schema {
color: var(--el-color-primary);
}
}
}
.el-sub-menu__title {
padding-left: 0 !important;
height: 30px !important;
line-height: 30px !important;
}
.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
padding-right: 10px;
}
.el-menu-item {
padding-left: 0 !important;
height: 20px !important;
line-height: 20px !important;
}
.el-icon {
margin: 0;
}
.el-sub-menu__icon-arrow {
top: inherit;
right: 10px;
}
}
.instances-pop-form {
.el-form-item {
margin-bottom: unset;

View File

@@ -1,16 +1,11 @@
<template>
<div>
<el-card>
<el-row>
<el-col :span="3">
<redis-instance-tree
@init-load-instances="initLoadInstances"
@change-instance="changeInstance"
@change-schema="loadInitSchema"
:instances="state.instances"
/>
<el-col :span="4">
<redis-instance-tree @init-load-instances="initLoadInstances" @change-instance="changeInstance"
@change-schema="loadInitSchema" :instances="state.instances" />
</el-col>
<el-col :span="19" style="border-left: 1px solid var(--el-card-border-color)">
<el-col :span="20" style="border-left: 1px solid var(--el-card-border-color);">
<el-col class="mt10">
<el-form class="search-form" label-position="right" :inline="true" label-width="60px">
<el-form-item label="key" label-width="40px">
@@ -42,7 +37,8 @@
</div>
</el-form>
</el-col>
<el-table v-loading="state.loading" :data="state.keys" stripe :highlight-current-row="true" style="cursor: pointer">
<el-table v-loading="state.loading" :data="state.keys" stripe :highlight-current-row="true"
style="cursor: pointer">
<el-table-column show-overflow-tooltip prop="key" label="key"></el-table-column>
<el-table-column prop="type" label="type" width="80">
<template #default="scope">
@@ -66,8 +62,6 @@
</el-col>
</el-row>
</el-card>
<div style="text-align: center; margin-top: 10px"></div>
<hash-value v-model:visible="hashValueDialog.visible" :operationType="dataEdit.operationType"
@@ -142,7 +136,7 @@ const state = reactive({
},
keys: [],
dbsize: 0,
instances:{tags:{}, tree:{}, dbs:{}, tables:{}}
instances: { tags: {}, tree: {}, dbs: {}, tables: {} }
});
const {
@@ -319,31 +313,31 @@ const getTypeColor = (type: string) => {
};
const initLoadInstances = async ()=>{
const initLoadInstances = async () => {
const res = await redisApi.redisList.request({});
if(!res.total) return
state.instances = {tags:{}, tree:{}, dbs:{}, tables:{}} ; // 初始化变量
if (!res.total) return
state.instances = { tags: {}, tree: {}, dbs: {}, tables: {} }; // 初始化变量
for (const db of res.list) {
let arr = state.instances.tree[db.tagId] || []
const {tagId, tagPath} = db
const { tagId, tagPath } = db
// tags
state.instances.tags[db.tagId]={tagId, tagPath}
state.instances.tags[db.tagId] = { tagId, tagPath }
// 实例
arr.push(db)
state.instances.tree[db.tagId] = arr;
}
}
const changeInstance = async (inst: any, fn: Function) => {
let dbs = state.instances.dbs[inst.id] || []
if(dbs.length <=0 ){
const res = await redisApi.redisInfo.request({ id: inst.id, host:inst.host });
for (let db in res.Keyspace){
dbs.push({
name: db,
keys: res.Keyspace[db]?.split(',')[0]?.split('=')[1] || 0
let dbs = inst.db.split(',').map((x: string) => {
return { name: `db${x}`, keys: 0 }
})
const res = await redisApi.redisInfo.request({ id: inst.id, host: inst.host, section: "Keyspace" });
for (let db in res.Keyspace) {
for (let d of dbs) {
if (db == d.name) {
d.keys = res.Keyspace[db]?.split(',')[0]?.split('=')[1] || 0
}
}
}
@@ -352,9 +346,9 @@ const changeInstance = async (inst: any, fn: Function) => {
}
/** 初始化加载db数据 */
const loadInitSchema = (inst: any, schema: string)=>{
const loadInitSchema = (inst: any, schema: string) => {
state.scanParam.id = inst.id
state.scanParam.db = schema.replace('db','')
state.scanParam.db = schema.replace('db', '')
scan()
}

View File

@@ -1,68 +1,46 @@
<template>
<div class="instances-box layout-aside">
<el-row type="flex" justify="space-between">
<el-col :span="24" :style="{
maxHeight: state.instanceMenuMaxHeight,
height: state.instanceMenuMaxHeight,
overflow:'auto'
}" class="el-scrollbar flex-auto">
<el-menu background-color="transparent" ref="menuRef">
<!-- 第一级tag -->
<el-sub-menu v-for="tag of instances.tags" :index="tag.tagPath" :key="tag.tagPath">
<tag-menu :instanceMenuMaxHeight="state.instanceMenuMaxHeight" :tags="instances.tags">
<template #submenu="props">
<el-sub-menu v-for="inst in instances.tree[props.tag.tagId]" :index="'redis-instance-' + inst.id"
:key="'redis-instance-' + inst.id" @click.stop="changeInstance(inst)">
<template #title>
<el-icon><FolderOpened color="#e6a23c"/></el-icon>
<span>{{ tag.tagPath }}</span>
</template>
<!-- 第二级数据库实例 -->
<el-sub-menu v-for="inst in instances.tree[tag.tagId]"
:index="'redis-instance-' + inst.id"
:key="'redis-instance-' + inst.id"
@click.prevent="changeInstance(inst)"
>
<template #title>
<el-popover
placement="right-start"
title="mongo数据库实例信息"
trigger="hover"
:width="210"
>
<el-popover placement="right-start" title="redis实例信息" trigger="hover" :width="210">
<template #reference>
<span>&nbsp;&nbsp;<el-icon><MostlyCloudy color="#409eff"/></el-icon>{{ inst.name }}</span>
<span>&nbsp;&nbsp;<el-icon>
<MostlyCloudy color="#409eff" />
</el-icon>{{ inst.name }}</span>
</template>
<template #default>
<el-form class="instances-pop-form" label-width="55px" :size="'small'">
<el-form-item label="名称:">{{inst.name}}</el-form-item>
<el-form-item label="链接:">{{inst.host}}</el-form-item>
<el-form-item label="名称:">{{ inst.name }}</el-form-item>
<el-form-item label="链接:">{{ inst.host }}</el-form-item>
<el-form-item label="备注:">{{ inst.remark }}</el-form-item>
</el-form>
</template>
</el-popover>
</template>
<!-- 第三级数据库 -->
<el-sub-menu v-for="db in instances.dbs[inst.id]"
:index="inst.id + db.name"
:key="inst.id + db.name"
:class="state.nowSchema === (inst.id+db.name) && 'checked'"
@click.prevent="changeSchema(inst, db.name)"
>
<el-menu-item v-for="db in instances.dbs[inst.id]" :index="inst.id + db.name" :key="inst.id + db.name"
:class="state.nowSchema === (inst.id + db.name) && 'checked'"
@click="changeSchema(inst, db.name)">
<template #title>
&nbsp;&nbsp;&nbsp;&nbsp;<el-icon><Coin color="#67c23a"/></el-icon>
&nbsp;&nbsp;&nbsp;&nbsp;<el-icon>
<Coin color="#67c23a" />
</el-icon>
<span class="checked-schema">
{{ db.name }} [{{db.keys}}]
{{ db.name }} [{{ db.keys }}]
</span>
</template>
</el-menu-item>
</el-sub-menu>
</el-sub-menu>
</el-sub-menu>
</el-menu>
</el-col>
</el-row>
</div>
</template>
</tag-menu>
</template>
<script lang="ts" setup>
import {onBeforeMount, onMounted, reactive, Ref, ref, watch} from 'vue';
import {store} from '@/store';
import { onBeforeMount, onMounted, reactive, Ref, ref, watch } from 'vue';
import { store } from '@/store';
import TagMenu from '../component/TagMenu.vue';
defineProps({
instances: {
@@ -70,15 +48,15 @@ defineProps({
},
})
const emits = defineEmits(['initLoadInstances','changeInstance','changeSchema'])
const emits = defineEmits(['initLoadInstances', 'changeInstance', 'changeSchema'])
onBeforeMount(async ()=>{
onBeforeMount(async () => {
await initLoadInstances()
setHeight()
})
const setHeight = () => {
state.instanceMenuMaxHeight = window.innerHeight - 140 + 'px';
state.instanceMenuMaxHeight = window.innerHeight - 115 + 'px';
}
const menuRef = ref(null) as Ref;
@@ -102,7 +80,7 @@ const initLoadInstances = () => {
* @param inst 选中的实例对象
* @param fn 选中的实例后的回调函数
*/
const changeInstance = (inst : any, fn?:Function) => {
const changeInstance = (inst: any, fn?: Function) => {
emits('changeInstance', inst, fn)
}
/**
@@ -110,7 +88,7 @@ const changeInstance = (inst : any, fn?:Function) => {
* @param inst 选中的实例对象
* @param schema 选中的数据库schema
*/
const changeSchema = (inst : any, schema: string) => {
const changeSchema = (inst: any, schema: string) => {
state.nowSchema = inst.id + schema
emits('changeSchema', inst, schema)
}
@@ -118,61 +96,28 @@ const changeSchema = (inst : any, schema: string) => {
const selectDb = async (val?: any) => {
const info = val || store.state.redisDbOptInfo.dbOptInfo
if (info && info.dbId) {
const {tagPath, dbId} = info
const { tagPath, dbId } = info
menuRef.value.open(tagPath);
menuRef.value.open('redis-instance-' + dbId);
await changeInstance({id: dbId}, async (dbs: any[]) => {
await changeSchema({id: dbId}, dbs[0]?.name)
await changeInstance({ id: dbId }, async (dbs: any[]) => {
await changeSchema({ id: dbId }, dbs[0]?.name)
})
}
}
onMounted(()=>{
onMounted(() => {
selectDb();
})
watch(()=>store.state.redisDbOptInfo.dbOptInfo, async newValue =>{
watch(() => store.state.redisDbOptInfo.dbOptInfo, async newValue => {
await selectDb(newValue)
})
</script>
<style lang="scss">
.instances-box {
.el-menu{
width: 275px;
}
.el-sub-menu{
.checked{
.checked-schema{
color: var(--el-color-primary);
}
}
}
.el-sub-menu__title{
padding-left: 0 !important;
height: 30px !important;
line-height: 30px !important;
}
.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title{
padding-right: 10px;
}
.el-menu-item{
padding-left: 0 !important;
height: 20px !important;
line-height: 20px !important;
}
.el-icon{
margin: 0;
}
.el-sub-menu__icon-arrow{
top:inherit;
right: 10px;
}
}
.instances-pop-form{
.el-form-item{
.instances-pop-form {
.el-form-item {
margin-bottom: unset;
}
}

View File

@@ -76,36 +76,42 @@ func (r *Redis) RedisInfo(rc *req.Ctx) {
g := rc.GinCtx
ri := r.RedisApp.GetRedisInstance(uint64(ginx.PathParamInt(g, "id")), 0)
var res string
var err error
section := rc.GinCtx.Query("section")
mode := ri.Info.Mode
ctx := context.Background()
var redisCli *redis.Client
if mode == "" || mode == entity.RedisModeStandalone || mode == entity.RedisModeSentinel {
res, err = ri.Cli.Info(ctx).Result()
redisCli = ri.Cli
} else if mode == entity.RedisModeCluster {
host := rc.GinCtx.Query("host")
biz.NotEmpty(host, "集群模式host信息不能为空")
clusterClient := ri.ClusterCli
var redisClient *redis.Client
// 遍历集群的master节点找到该redis client
clusterClient.ForEachMaster(ctx, func(ctx context.Context, client *redis.Client) error {
if host == client.Options().Addr {
redisClient = client
redisCli = client
}
return nil
})
if redisClient == nil {
if redisCli == nil {
// 遍历集群的slave节点找到该redis client
clusterClient.ForEachSlave(ctx, func(ctx context.Context, client *redis.Client) error {
if host == client.Options().Addr {
redisClient = client
redisCli = client
}
return nil
})
}
biz.NotNil(redisClient, "该实例不在该集群中")
res, err = redisClient.Info(ctx).Result()
biz.NotNil(redisCli, "该实例不在该集群中")
}
var res string
var err error
if section == "" {
res, err = ri.Cli.Info(ctx).Result()
} else {
res, err = ri.Cli.Info(ctx, section).Result()
}
biz.ErrIsNilAppendErr(err, "获取redis info失败: %s")

View File

@@ -7,8 +7,6 @@ type Redis struct {
Name *string `json:"name"`
Host *string `json:"host"`
Db string `json:"db"`
ProjectId *int64 `json:"projectId"`
Project *string `json:"project"`
Mode *string `json:"mode"`
EnableSshTunnel *int8 `json:"enableSshTunnel"` // 是否启用ssh隧道
SshTunnelMachineId *uint64 `json:"sshTunnelMachineId"` // ssh隧道机器id