You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.5 KiB

<template>
<div class="app-container" ref="containerRef">
<!-- 左侧 SQL 编辑区 -->
<div class="sql-container" :style="{ width: leftWidth + 'px' }">
<!-- 工具栏 -->
<div class="toolbar">
<el-select
v-model="dbType"
placeholder="选择数据库类型"
size="small"
style="width: 160px"
>
<el-option label="MySQL" value="MYSQL" />
<el-option label="PostgreSQL" value="PG" />
<el-option label="SQL Server" value="MSSQL" />
<el-option label="Oracle" value="ORACLE" />
</el-select>
<el-button
type="primary"
size="small"
style="margin-left: 10px"
@click="executeSql"
>
执行
</el-button>
</div>
<!-- SQL 编辑器 -->
<SQLCodeMirror
v-if="activeColumnTab === 'proc'"
:data="procStr"
:dbType="dbType"
/>
</div>
<!-- 分隔条 -->
<div class="divider" @mousedown="startDragging"></div>
<!-- 右侧 血缘关系图 -->
<div class="relation-container">
<BloodRelation :currentTable="currentMetaData" :data="bloodRelation" />
</div>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import { getMetaDataBloodRelship } from '@/api/meta/metaInfo'
import BloodRelation from '@/views/meta/metaInfo/bloodRelationSql.vue'
import SQLCodeMirror from '@/components/codemirror/SQLCodeMirrorSqlFlow.vue'
// ========================= 数据定义 =========================
const activeColumnTab = ref('proc')
const procStr = ref('SELECT * FROM users LIMIT 100;')
const dbType = ref('MYSQL')
const containerRef = ref(null)
// 当前元数据信息
const currentMetaData = reactive({
tabEngName: 't_dim_comp',
tabCnName: '公司维度表',
ssysCd: 'PG_CONN',
ssysId: 1,
mdlName: 'public',
tabCrrctName: '',
tabDesc: '',
govFlag: null,
pic: '',
tags: []
})
// 血缘图数据
const bloodRelation = ref([])
// ========================= 拖拽逻辑 =========================
const leftWidth = ref(600)
const isDragging = ref(false)
let startX = 0
let startWidth = 0
const startDragging = e => {
isDragging.value = true
startX = e.clientX
startWidth = leftWidth.value
document.body.style.userSelect = 'none' // 禁止文字选中
document.addEventListener('mousemove', handleDragging)
document.addEventListener('mouseup', stopDragging)
}
const handleDragging = e => {
if (!isDragging.value) return
const containerLeft = containerRef.value?.getBoundingClientRect().left || 0
const delta = e.clientX - startX
const newWidth = startWidth + delta
const minWidth = 300
const maxWidth = window.innerWidth - 400 // 保证右侧至少有空间
leftWidth.value = Math.min(Math.max(newWidth, minWidth), maxWidth)
}
const stopDragging = () => {
isDragging.value = false
document.body.style.userSelect = '' // 恢复文字选中
document.removeEventListener('mousemove', handleDragging)
document.removeEventListener('mouseup', stopDragging)
}
// ========================= 方法 =========================
const changeBloodOption = () => {
getMetaDataBloodRelship(currentMetaData.ssysId).then(res => {
bloodRelation.value = res.data
})
}
const executeSql = () => {
console.log('执行 SQL:', procStr.value)
console.log('数据库类型:', dbType.value)
ElMessage.success(`已在 ${dbType.value} 数据库中执行 SQL`)
}
// ========================= 生命周期 =========================
onMounted(() => {
changeBloodOption()
})
onBeforeUnmount(() => {
stopDragging()
})
</script>
<style scoped>
.app-container {
display: flex;
flex-direction: row;
height: 100vh;
width: 100%;
overflow: hidden;
}
/* 左侧 SQL 编辑区 */
.sql-container {
height: 100%;
background: #fafafa;
border-right: 1px solid #e0e0e0;
overflow: auto;
transition: width 0.1s ease-out;
display: flex;
flex-direction: column;
}
/* 工具栏 */
.toolbar {
display: flex;
align-items: center;
background: #f5f7fa;
border-bottom: 1px solid #e0e0e0;
padding: 8px 12px;
height: 45px;
}
/* 分隔条 */
.divider {
width: 6px;
cursor: col-resize;
background-color: #dcdcdc;
transition: background-color 0.2s;
flex-shrink: 0;
}
.divider:hover {
background-color: #aaa;
}
/* 右侧 血缘关系图 */
.relation-container {
flex: 1;
height: 100%;
overflow: hidden;
padding: 8px;
background: #fff;
}
</style>