Files
mayfly-go/frontend/src/views/ops/db/InstanceList.vue

225 lines
8.2 KiB
Vue
Raw Normal View History

2023-08-27 11:07:29 +08:00
<template>
<div class="db-list">
<page-table
ref="pageTableRef"
:page-api="dbApi.instances"
2024-04-12 13:24:20 +08:00
:data-handler-fn="handleData"
2023-12-12 23:31:53 +08:00
:searchItems="searchItems"
2023-08-27 11:07:29 +08:00
v-model:query-form="query"
:show-selection="true"
v-model:selection-data="state.selectionData"
:columns="columns"
lazy
2023-08-27 11:07:29 +08:00
>
2023-12-12 23:31:53 +08:00
<template #tableHeader>
2023-08-27 11:07:29 +08:00
<el-button v-auth="perms.saveInstance" type="primary" icon="plus" @click="editInstance(false)">添加</el-button>
2023-09-05 12:49:12 +08:00
<el-button v-auth="perms.delInstance" :disabled="selectionData.length < 1" @click="deleteInstance()" type="danger" icon="delete"
>删除</el-button
>
2023-08-27 11:07:29 +08:00
</template>
<template #tagPath="{ data }">
<ResourceTags :tags="data.tags" />
</template>
2024-04-12 13:24:20 +08:00
<template #authCert="{ data }">
<ResourceAuthCert v-model:select-auth-cert="data.selectAuthCert" :auth-certs="data.authCerts" />
</template>
<template #type="{ data }">
<el-tooltip :content="getDbDialect(data.type).getInfo().name" placement="top">
<SvgIcon :name="getDbDialect(data.type).getInfo().icon" :size="20" />
</el-tooltip>
</template>
2023-08-27 11:07:29 +08:00
<template #action="{ data }">
2023-11-09 12:11:11 +08:00
<el-button @click="showInfo(data)" link>详情</el-button>
2023-08-27 11:07:29 +08:00
<el-button v-if="actionBtns[perms.saveInstance]" @click="editInstance(data)" type="primary" link>编辑</el-button>
<el-button v-if="actionBtns[perms.saveDb]" @click="editDb(data)" type="primary" link>库管理</el-button>
2023-08-27 11:07:29 +08:00
</template>
</page-table>
2023-12-27 22:59:20 +08:00
<el-dialog v-model="infoDialog.visible" title="详情">
<el-descriptions :column="3" border>
2023-08-27 11:07:29 +08:00
<el-descriptions-item :span="2" label="名称">{{ infoDialog.data.name }}</el-descriptions-item>
<el-descriptions-item :span="1" label="id">{{ infoDialog.data.id }}</el-descriptions-item>
<el-descriptions-item :span="2" label="主机">{{ infoDialog.data.host }}</el-descriptions-item>
<el-descriptions-item :span="1" label="端口">{{ infoDialog.data.port }}</el-descriptions-item>
<el-descriptions-item :span="1" label="类型">{{ infoDialog.data.type }}</el-descriptions-item>
<el-descriptions-item :span="3" label="连接参数">{{ infoDialog.data.params }}</el-descriptions-item>
<el-descriptions-item :span="3" label="备注">{{ infoDialog.data.remark }}</el-descriptions-item>
<el-descriptions-item :span="3" label="SSH隧道">{{ infoDialog.data.sshTunnelMachineId > 0 ? '是' : '否' }} </el-descriptions-item>
<el-descriptions-item :span="2" label="创建时间">{{ formatDate(infoDialog.data.createTime) }} </el-descriptions-item>
2023-08-27 11:07:29 +08:00
<el-descriptions-item :span="1" label="创建者">{{ infoDialog.data.creator }}</el-descriptions-item>
<el-descriptions-item :span="2" label="更新时间">{{ formatDate(infoDialog.data.updateTime) }} </el-descriptions-item>
2023-08-27 11:07:29 +08:00
<el-descriptions-item :span="1" label="修改者">{{ infoDialog.data.modifier }}</el-descriptions-item>
</el-descriptions>
</el-dialog>
2023-09-05 12:49:12 +08:00
<instance-edit
@val-change="search()"
2023-09-05 12:49:12 +08:00
:title="instanceEditDialog.title"
v-model:visible="instanceEditDialog.visible"
v-model:data="instanceEditDialog.data"
></instance-edit>
<DbList :title="dbEditDialog.title" v-model:visible="dbEditDialog.visible" :instance="dbEditDialog.instance" />
2023-08-27 11:07:29 +08:00
</div>
</template>
<script lang="ts" setup>
import { defineAsyncComponent, onMounted, reactive, ref, Ref, toRefs } from 'vue';
2023-08-27 11:07:29 +08:00
import { ElMessage, ElMessageBox } from 'element-plus';
import { dbApi } from './api';
import { formatDate } from '@/common/utils/format';
2023-08-27 11:07:29 +08:00
import PageTable from '@/components/pagetable/PageTable.vue';
2023-12-12 23:31:53 +08:00
import { TableColumn } from '@/components/pagetable';
2023-08-27 11:07:29 +08:00
import { hasPerms } from '@/components/auth/auth';
import SvgIcon from '@/components/svgIcon/index.vue';
import { getDbDialect } from './dialect';
2023-12-12 23:31:53 +08:00
import { SearchItem } from '@/components/SearchForm';
2024-04-12 13:24:20 +08:00
import ResourceAuthCert from '../component/ResourceAuthCert.vue';
import ResourceTags from '../component/ResourceTags.vue';
import { getTagPathSearchItem } from '../component/tag';
import { TagResourceTypeEnum } from '@/common/commonEnum';
2023-08-27 11:07:29 +08:00
const InstanceEdit = defineAsyncComponent(() => import('./InstanceEdit.vue'));
const DbList = defineAsyncComponent(() => import('./DbList.vue'));
const props = defineProps({
lazy: {
type: [Boolean],
default: false,
},
});
2023-08-27 11:07:29 +08:00
const perms = {
2023-09-05 12:49:12 +08:00
saveInstance: 'db:instance:save',
delInstance: 'db:instance:del',
saveDb: 'db:save',
2023-08-27 11:07:29 +08:00
};
const searchItems = [SearchItem.input('keyword', '关键字').withPlaceholder('host / 名称 / 编号'), getTagPathSearchItem(TagResourceTypeEnum.Db.value)];
2023-08-27 11:07:29 +08:00
const columns = ref([
TableColumn.new('tags[0].tagPath', '关联标签').isSlot('tagPath').setAddWidth(20),
2023-08-27 11:07:29 +08:00
TableColumn.new('name', '名称'),
TableColumn.new('type', '类型').isSlot().setAddWidth(-15).alignCenter(),
2023-11-09 12:11:11 +08:00
TableColumn.new('host', 'host:port').setFormatFunc((data: any) => `${data.host}:${data.port}`),
2024-04-12 13:24:20 +08:00
TableColumn.new('authCerts[0].username', '授权凭证').isSlot('authCert').setAddWidth(10),
2023-11-09 12:11:11 +08:00
TableColumn.new('params', '连接参数'),
2023-08-27 11:07:29 +08:00
TableColumn.new('remark', '备注'),
TableColumn.new('code', '编号'),
2023-08-27 11:07:29 +08:00
]);
// 该用户拥有的的操作列按钮权限
const actionBtns: any = hasPerms(Object.values(perms));
const actionColumn = TableColumn.new('action', '操作').isSlot().setMinWidth(180).fixedRight().alignCenter();
const pageTableRef: Ref<any> = ref(null);
2023-08-27 11:07:29 +08:00
const state = reactive({
row: {},
dbId: 0,
db: '',
/**
* 选中的数据
*/
selectionData: [],
/**
* 查询条件
*/
query: {
name: null,
tagPath: '',
2023-08-27 11:07:29 +08:00
pageNum: 1,
pageSize: 0,
2023-08-27 11:07:29 +08:00
},
infoDialog: {
visible: false,
data: null as any,
},
instanceEditDialog: {
visible: false,
data: null as any,
title: '新增数据库实例',
},
dbEditDialog: {
visible: false,
instance: null as any,
title: '新增数据库实例',
},
2023-08-27 11:07:29 +08:00
});
const { selectionData, query, infoDialog, instanceEditDialog, dbEditDialog } = toRefs(state);
2023-08-27 11:07:29 +08:00
onMounted(async () => {
if (Object.keys(actionBtns).length > 0) {
columns.value.push(actionColumn);
}
if (!props.lazy) {
search();
}
2023-08-27 11:07:29 +08:00
});
const search = (tagPath: string = '') => {
if (tagPath) {
state.query.tagPath = tagPath;
}
pageTableRef.value.search();
2023-08-27 11:07:29 +08:00
};
2024-04-12 13:24:20 +08:00
const handleData = (res: any) => {
const dataList = res.list;
// 赋值授权凭证
for (let x of dataList) {
x.selectAuthCert = x.authCerts[0];
}
return res;
};
2023-08-27 11:07:29 +08:00
const showInfo = (info: any) => {
state.infoDialog.data = info;
state.infoDialog.visible = true;
};
const editInstance = async (data: any) => {
if (!data) {
state.instanceEditDialog.data = null;
state.instanceEditDialog.title = '新增数据库实例';
} else {
state.instanceEditDialog.data = data;
state.instanceEditDialog.title = '修改数据库实例';
}
state.instanceEditDialog.visible = true;
};
2024-02-22 21:03:13 +08:00
const deleteInstance = async () => {
2023-08-27 11:07:29 +08:00
try {
2024-02-22 21:03:13 +08:00
await ElMessageBox.confirm(`确定删除数据库实例【${state.selectionData.map((x: any) => x.name).join(', ')}】?`, '提示', {
2023-08-27 11:07:29 +08:00
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
});
2024-02-22 21:03:13 +08:00
await dbApi.deleteInstance.request({ id: state.selectionData.map((x: any) => x.id).join(',') });
2023-08-27 11:07:29 +08:00
ElMessage.success('删除成功');
search();
2023-11-09 12:11:11 +08:00
} catch (err) {
//
}
2023-08-27 11:07:29 +08:00
};
const editDb = (data: any) => {
state.dbEditDialog.instance = data;
state.dbEditDialog.title = `管理 "${data.name}" 数据库`;
state.dbEditDialog.visible = true;
};
defineExpose({ search });
2023-08-27 11:07:29 +08:00
</script>
<style lang="scss"></style>