Files
mayfly-go/mayfly_go_web/src/views/ops/mongo/MongoDbs.vue
2023-08-25 10:20:32 +08:00

353 lines
14 KiB
Vue

<template>
<div>
<el-dialog width="800px" title="数据库列表" :before-close="close" v-model="databaseDialog.visible">
<div class="mb5">
<el-button @click="showCreateDbDialog" type="primary" icon="plus" size="small">新建</el-button>
</div>
<el-table :data="databaseDialog.data" :max-height="500">
<el-table-column min-width="130" property="Name" label="库名" />
<el-table-column min-width="90" property="SizeOnDisk" label="size">
<template #default="scope">
{{ formatByteSize(scope.row.SizeOnDisk) }}
</template>
</el-table-column>
<el-table-column min-width="80" property="Empty" label="是否为空" />
<el-table-column min-width="150" label="操作">
<template #default="scope">
<el-link type="success" @click="showDatabaseStats(scope.row.Name)" plain size="small" :underline="false">stats</el-link>
<el-divider direction="vertical" border-style="dashed" />
<el-link type="primary" @click="showCollections(scope.row.Name)" plain size="small" :underline="false">集合</el-link>
<el-divider direction="vertical" border-style="dashed" />
<el-popconfirm @confirm="onDeleteDb(scope.row.Name)" title="确定删除该库?">
<template #reference>
<el-link type="danger" plain size="small" :underline="false">删除</el-link>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-dialog width="700px" :title="databaseDialog.statsDialog.title" v-model="databaseDialog.statsDialog.visible">
<el-descriptions title="库状态信息" :column="3" border>
<el-descriptions-item label="db" label-align="right" align="center">
{{ databaseDialog.statsDialog.data.db }}
</el-descriptions-item>
<el-descriptions-item label="collections" label-align="right" align="center">
{{ databaseDialog.statsDialog.data.collections }}
</el-descriptions-item>
<el-descriptions-item label="objects" label-align="right" align="center">
{{ databaseDialog.statsDialog.data.objects }}
</el-descriptions-item>
<el-descriptions-item label="indexes" label-align="right" align="center">
{{ databaseDialog.statsDialog.data.indexes }}
</el-descriptions-item>
<el-descriptions-item label="avgObjSize" label-align="right" align="center">
{{ formatByteSize(databaseDialog.statsDialog.data.avgObjSize) }}
</el-descriptions-item>
<el-descriptions-item label="dataSize" label-align="right" align="center">
{{ formatByteSize(databaseDialog.statsDialog.data.dataSize) }}
</el-descriptions-item>
<el-descriptions-item label="totalSize" label-align="right" align="center">
{{ formatByteSize(databaseDialog.statsDialog.data.totalSize) }}
</el-descriptions-item>
<el-descriptions-item label="storageSize" label-align="right" align="center">
{{ formatByteSize(databaseDialog.statsDialog.data.storageSize) }}
</el-descriptions-item>
<el-descriptions-item label="fsTotalSize" label-align="right" align="center">
{{ formatByteSize(databaseDialog.statsDialog.data.fsTotalSize) }}
</el-descriptions-item>
<el-descriptions-item label="fsUsedSize" label-align="right" align="center">
{{ formatByteSize(databaseDialog.statsDialog.data.fsUsedSize) }}
</el-descriptions-item>
<el-descriptions-item label="indexSize" label-align="right" align="center">
{{ formatByteSize(databaseDialog.statsDialog.data.indexSize) }}
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</el-dialog>
<el-dialog width="600px" :title="collectionsDialog.title" v-model="collectionsDialog.visible">
<div class="mb5">
<el-button @click="showCreateCollectionDialog" type="primary" icon="plus" size="small">新建</el-button>
</div>
<el-table stripe :data="collectionsDialog.data" :max-height="500">
<el-table-column prop="name" label="名称" show-overflow-tooltip> </el-table-column>
<el-table-column min-width="80" label="操作">
<template #default="scope">
<el-link type="success" @click="showCollectionStats(scope.row.name)" plain size="small" :underline="false">stats</el-link>
<el-divider direction="vertical" border-style="dashed" />
<el-popconfirm @confirm="onDeleteCollection(scope.row.name)" width="160" title="确定删除该集合?">
<template #reference>
<el-link type="danger" plain size="small" :underline="false">删除</el-link>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<el-dialog width="700px" :title="collectionsDialog.statsDialog.title" v-model="collectionsDialog.statsDialog.visible">
<el-descriptions title="集合状态信息" :column="3" border>
<el-descriptions-item label="ns" label-align="right" :span="2" align="center">
{{ collectionsDialog.statsDialog.data.ns }}
</el-descriptions-item>
<el-descriptions-item label="count" label-align="right" align="center">
{{ collectionsDialog.statsDialog.data.count }}
</el-descriptions-item>
<el-descriptions-item label="avgObjSize" label-align="right" align="center">
{{ formatByteSize(collectionsDialog.statsDialog.data.avgObjSize) }}
</el-descriptions-item>
<el-descriptions-item label="nindexes" label-align="right" align="center">
{{ collectionsDialog.statsDialog.data.nindexes }}
</el-descriptions-item>
<el-descriptions-item label="size" label-align="right" align="center">
{{ formatByteSize(collectionsDialog.statsDialog.data.size) }}
</el-descriptions-item>
<el-descriptions-item label="totalSize" label-align="right" align="center">
{{ formatByteSize(collectionsDialog.statsDialog.data.totalSize) }}
</el-descriptions-item>
<el-descriptions-item label="storageSize" label-align="right" align="center">
{{ formatByteSize(collectionsDialog.statsDialog.data.storageSize) }}
</el-descriptions-item>
<el-descriptions-item label="freeStorageSize" label-align="right" align="center">
{{ formatByteSize(collectionsDialog.statsDialog.data.freeStorageSize) }}
</el-descriptions-item>
</el-descriptions>
</el-dialog>
</el-dialog>
<el-dialog width="400px" title="新建库&集合" v-model="createDbDialog.visible" :destroy-on-close="true">
<el-form :model="createDbDialog.form" label-width="auto">
<el-form-item prop="dbName" label="库名" required>
<el-input v-model="createDbDialog.form.dbName" clearable></el-input>
</el-form-item>
<el-form-item prop="collectionName" label="集合名" required>
<el-input v-model="createDbDialog.form.collectionName" clearable></el-input>
</el-form-item>
</el-form>
<template #footer>
<div>
<el-button @click="createDbDialog.visible = false"> </el-button>
<el-button @click="onCreateDb" type="primary"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog width="400px" title="新建集合" v-model="createCollectionDialog.visible" :destroy-on-close="true">
<el-form :model="createCollectionDialog.form" label-width="auto">
<el-form-item prop="name" label="集合名" required>
<el-input v-model="createCollectionDialog.form.name" clearable></el-input>
</el-form-item>
</el-form>
<template #footer>
<div>
<el-button @click="createCollectionDialog.visible = false"> </el-button>
<el-button @click="onCreateCollection" type="primary"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import { mongoApi } from './api';
import { watch, toRefs, reactive } from 'vue';
import { ElMessage } from 'element-plus';
import { formatByteSize } from '@/common/utils/format';
const props = defineProps({
visible: {
type: Boolean,
},
id: {
type: [Number],
required: true,
},
});
//定义事件
const emit = defineEmits(['update:visible']);
const state = reactive({
databaseDialog: {
visible: false,
data: [],
statsDialog: {
visible: false,
data: {} as any,
title: '',
},
},
collectionsDialog: {
database: '',
visible: false,
data: [],
title: '',
statsDialog: {
visible: false,
data: {} as any,
title: '',
},
},
createCollectionDialog: {
visible: false,
form: {
name: '',
},
},
createDbDialog: {
visible: false,
form: {
dbName: '',
collectionName: '',
},
},
});
const { databaseDialog, collectionsDialog, createCollectionDialog, createDbDialog } = toRefs(state);
watch(props, async (newValue: any) => {
if (!newValue.visible) {
state.databaseDialog.visible = false;
return;
}
showDatabases();
});
const close = () => {
emit('update:visible', false);
};
const showDatabases = async () => {
state.databaseDialog.data = (await mongoApi.databases.request({ id: props.id })).Databases;
state.databaseDialog.visible = true;
};
const showDatabaseStats = async (dbName: string) => {
state.databaseDialog.statsDialog.data = await mongoApi.runCommand.request({
id: props.id,
database: dbName,
command: [
{
dbStats: 1,
},
],
});
state.databaseDialog.statsDialog.title = `'${dbName}' stats`;
state.databaseDialog.statsDialog.visible = true;
};
const showCollections = async (database: string) => {
state.collectionsDialog.database = database;
state.collectionsDialog.data = [];
setCollections(database);
state.collectionsDialog.title = `'${database}' 集合`;
state.collectionsDialog.visible = true;
};
const setCollections = async (database: string) => {
const res = await mongoApi.collections.request({ id: props.id, database });
const collections = [] as any;
for (let r of res) {
collections.push({ name: r });
}
state.collectionsDialog.data = collections;
};
/**
* 显示集合状态
*/
const showCollectionStats = async (collection: string) => {
state.collectionsDialog.statsDialog.data = await mongoApi.runCommand.request({
id: props.id,
database: state.collectionsDialog.database,
command: [
{
collStats: collection,
},
],
});
state.collectionsDialog.statsDialog.title = `'${collection}' stats`;
state.collectionsDialog.statsDialog.visible = true;
};
/**
* 删除集合
*/
const onDeleteCollection = async (collection: string) => {
await mongoApi.runCommand.request({
id: props.id,
database: state.collectionsDialog.database,
command: [
{
drop: collection,
},
],
});
ElMessage.success('集合删除成功');
setCollections(state.collectionsDialog.database);
};
const showCreateCollectionDialog = () => {
state.createCollectionDialog.visible = true;
};
const onCreateCollection = async () => {
const form = state.createCollectionDialog.form;
await mongoApi.runCommand.request({
id: props.id,
database: state.collectionsDialog.database,
command: [
{
create: form.name,
},
],
});
ElMessage.success('集合创建成功');
state.createCollectionDialog.visible = false;
state.createCollectionDialog.form = {} as any;
setCollections(state.collectionsDialog.database);
};
const showCreateDbDialog = () => {
state.createDbDialog.visible = true;
};
const onCreateDb = async () => {
const form = state.createDbDialog.form;
await mongoApi.runCommand.request({
id: props.id,
database: form.dbName,
command: [
{
create: form.collectionName,
},
],
});
ElMessage.success('数据库与集合创建成功');
state.createDbDialog.visible = false;
state.createDbDialog.form = {} as any;
showDatabases();
};
const onDeleteDb = async (db: string) => {
await mongoApi.runCommand.request({
id: props.id,
database: db,
command: [
{
dropDatabase: 1,
},
],
});
ElMessage.success('库删除成功');
showDatabases();
};
</script>
<style></style>