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.
 
 
 
 
 

249 lines
6.1 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: 140px; margin-left: 10px;"
>
<el-option label="MySQL" value="MYSQL" />
<el-option label="PostgreSQL" value="POSTGRESQL" />
<el-option label="SQL Server" value="MSSQL" />
<el-option label="Oracle" value="ORACLE" />
<el-option label="DB2" value="DB2" />
</el-select>
<!-- 系统选择 -->
<el-select
v-model="selectedSystem"
placeholder="选择系统"
size="small"
style="width: 160px"
>
<el-option
v-for="sys in dsSysList"
:key="sys.id"
:label="sys.name"
:value="sys.id"
/>
</el-select>
<!-- 模式 -->
<el-input
v-model="defaultModel"
placeholder="输入模式名"
size="small"
style="width: 140px; margin-left: 10px;"
clearable
/>
<!-- 执行按钮 -->
<el-button
type="primary"
size="small"
style="margin-left: 10px"
@click="executeSql"
>
执行
</el-button>
</div>
<!-- SQL 编辑器 -->
<SQLCodeMirror
v-model="procStr"
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, runBloodAnalysisBySql } from '@/api/meta/metaInfo'
import BloodRelation from '@/views/meta/metaInfo/bloodRelationSql.vue'
import SQLCodeMirror from '@/components/codemirror/SQLCodeMirrorSqlFlow.vue'
import useUserStore from '@/store/modules/user'
import cache from "@/plugins/cache";
const userStore = useUserStore()
const dsSysList = userStore.dsSysList
// ========================= 数据定义 =========================
const activeColumnTab = ref('proc')
const procStr = ref('')
const dbType = ref('MYSQL')
const containerRef = ref(null)
const childRef = ref(null)
// 当前选中系统
const selectedSystem = ref(dsSysList?.[0]?.id || null)
// 模式(可手动输入)
const defaultModel = ref('')
// 当前元数据信息
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 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
})
}
/**
* 执行 SQL 并生成血缘分析图
*/
const executeSql = async () => {
if (!selectedSystem.value) {
ElMessage.warning('请选择系统')
return
}
if (!procStr.value.trim()) {
ElMessage.warning('请输入 SQL 语句')
return
}
const params = {
sqlType: dbType.value,
defaultSystem: selectedSystem.value,
defaultModel: defaultModel.value || '',
sql: procStr.value,
userName: cache.local.get("username"),
password: cache.local.get("password")
}
try {
ElMessage.info('正在执行血缘分析,请稍候...')
const res = await runBloodAnalysisBySql(params)
if (res?.data) {
bloodRelation.value = res.data
ElMessage.success('血缘分析执行成功')
} else {
ElMessage.warning('未返回血缘数据')
}
} catch (err) {
console.error(err)
ElMessage.error('执行血缘分析失败')
}
}
// ========================= 生命周期 =========================
onMounted(() => {
changeBloodOption() // 初始化时仅加载血缘,不执行SQL
})
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>