123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- <template>
- <div class="main-box">
- <div class="card filter">
- <el-tree
- class="scroller"
- :load="loadNode"
- :expand-on-click-node="true"
- :highlight-current="true"
- :render-content="renderContent"
- @node-click="handleNodeClick"
- :lazy="true"
- >
- </el-tree>
- </div>
- <div class="table-box card content-box-c">
- <div class="table-container">
- <span>当前表:{{ currentNode.schemaName }} / {{ currentNode.tableName }}</span>
- <el-tabs v-model="activeName" class="demo-tabs">
- <el-tab-pane label="基本信息" name="1">
- <el-descriptions title="元数据" size="small" :column="1" colon border>
- <el-descriptions-item label="表名称">{{ tableMeta.tableName }}</el-descriptions-item>
- <el-descriptions-item label="表类型">{{ tableMeta.type }}</el-descriptions-item>
- <el-descriptions-item label="模式名">{{ tableMeta.schemaName }}</el-descriptions-item>
- <el-descriptions-item label="表注释">
- <el-input type="textarea" :rows="2" v-model="tableMeta.remarks" auto-complete="off" :readonly="true"></el-input>
- </el-descriptions-item>
- <el-descriptions-item label="建表DDL">
- <el-input type="textarea" :rows="16" v-model="tableMeta.createSql" auto-complete="off" :readonly="true"></el-input>
- </el-descriptions-item>
- </el-descriptions>
- </el-tab-pane>
- <el-tab-pane label="字段信息" name="2">
- <ProTable :pagination="false" :is-show-search="false" :tool-button="false" :columns="fieldColumns" :data="tableMeta.columns">
- <!-- 表格操作 -->
- <template #empty>
- <span>单击左侧展开"数据源"来查看表的元数据记录</span>
- </template>
- </ProTable>
- </el-tab-pane>
- <el-tab-pane label="索引信息" name="3">
- <ProTable :pagination="false" :is-show-search="false" :tool-button="false" :columns="indexColumns" :data="tableMeta.indexes">
- <!-- 表格操作 -->
- <template #empty>
- <span>单击左侧展开"数据源"来查看表的元数据记录</span>
- </template>
- </ProTable>
- </el-tab-pane>
- <el-tab-pane label="取样数据" name="4">
- <el-table :data="sampleData?.rows" border>
- <template #empty>
- <span>单击左侧展开"数据源导航树"来查看表的数据记录</span>
- </template>
- <el-table-column v-for="(item, index) in sampleData?.columns" :prop="item" :label="item" :key="index" show-overflow-tooltip>
- </el-table-column>
- </el-table>
- </el-tab-pane>
- </el-tabs>
- </div>
- </div>
- </div>
- </template>
- <script setup lang="tsx" name="UserManage">
- import { ref, reactive } from 'vue'
- // import TreeFilter from '@/components/TreeFilter/index.vue'
- import { getNameListApi } from '@/api/modules/db/connection'
- import { getSchemasApi, getTablesApi, getTablesMetaApi, getTablesDataApi } from '@/api/modules/db/metadata'
- // import type { TabsPaneContext } from 'element-plus'
- import ProTable from '@/components/ProTable/index.vue'
- import { ColumnProps } from '@/components/ProTable/interface'
- const activeName = ref('1')
- const tableMeta = ref({
- tableName: '-',
- schemaName: '-',
- remarks: '',
- type: '-',
- createSql: '',
- primaryKeys: [],
- columns: [],
- indexes: []
- })
- const currentNode = ref({
- tableName: '-',
- schemaName: '-'
- })
- let sampleData = ref<any>()
- // const handleClick = (tab: TabsPaneContext, event: Event) => {
- // console.log(tab, event)
- // }
- const loadNode = (node, resolve) => {
- if (node.level === 0) {
- const rootNode = [{ label: '数据源导航树', value: 0, hasChild: true, children: 'child' }]
- return resolve(rootNode)
- }
- setTimeout(() => {
- if (node.level === 1) {
- getNameListApi().then(res => {
- res.data.forEach(item => {
- item['label'] = item.name
- item['parent'] = 0
- item['value'] = item.id
- item['hasChild'] = true
- item['children'] = 'child'
- })
- resolve(res.data)
- })
- } else if (node.level === 2) {
- getSchemasApi(node.data.value).then(res => {
- res.data.forEach(item => {
- item['label'] = item.schema
- item['parent'] = node.data.value
- item['value'] = item.connection
- item['hasChild'] = true
- item['children'] = 'child'
- })
- resolve(res.data)
- })
- } else if (node.level === 3) {
- getTablesApi(node.data.parent, { schema: node.data.label }).then(res => {
- res.data.forEach(item => {
- item['label'] = item.tableName
- item['parent'] = node.data.label
- item['id'] = node.data.parent
- item['value'] = item.type
- item['hasChild'] = false
- item['children'] = 'child'
- })
- resolve(res.data)
- })
- } else if (node.level == 4) {
- resolve([])
- } else {
- resolve([])
- }
- }, 500)
- }
- const handleNodeClick = data => {
- let id = data.id
- let schema = data.schemaName
- let table = data.tableName
- if (!data.hasChild && id && schema && table) {
- activeName.value = '1'
- getTablesMetaApi(id, { schema, table }).then(res => {
- tableMeta.value = res.data
- currentNode.value.tableName = table
- currentNode.value.schemaName = schema
- })
- getTablesDataApi(id, { schema, table }).then(res => {
- sampleData.value = res.data
- })
- }
- }
- const renderContent = (h, { node, data }) => {
- if (node.level === 1) {
- return (
- <div class="custom-tree-node">
- <i class="el-icon-takeaway-box"></i>
- <span>{data.label}</span>
- </div>
- )
- } else if (node.level === 2) {
- return (
- <div class="custom-tree-node">
- <i class="el-icon-folder-opened"></i>
- <span>{data.label}</span>
- </div>
- )
- } else if (node.level === 3) {
- return (
- <div class="custom-tree-node">
- <i class="iconfont icon-shujuku1"></i>
- <span>{data.label}</span>
- </div>
- )
- } else {
- let icon_pic = 'iconfont icon-shitu_biaoge'
- if (data.value === 'VIEW') {
- icon_pic = 'iconfont icon-viewList'
- }
- return (
- <div class="custom-tree-node">
- <i class={icon_pic}></i>
- <el-tooltip class="item" content={node.label} effect="light" placement="left">
- <span>{data.label}</span>
- </el-tooltip>
- </div>
- )
- }
- }
- // 表格配置项
- const fieldColumns = reactive<ColumnProps<any>[]>([
- { prop: 'fieldName', label: '名称' },
- { prop: 'typeName', label: '类型' },
- { prop: 'fieldType', label: 'jdbcType' },
- { prop: 'displaySize', label: '长度' },
- { prop: 'precision', label: '精度' },
- { prop: 'scale', label: '位数' },
- { prop: 'isPrimaryKey', label: '主键' },
- { prop: 'isAutoIncrement', label: '自增' },
- { prop: 'isNullable', label: '可空' },
- { prop: 'remarks', label: '注释' }
- ])
- const indexColumns = reactive<ColumnProps<any>[]>([
- { prop: 'indexType', label: '索引类型' },
- { prop: 'indexName', label: '索引名称' },
- { prop: 'indexFields', label: '索引字段' }
- ])
- </script>
- <style scoped lang="scss">
- @import './index.scss';
- </style>
|