mirror of
https://gh-proxy.org/https://github.com/klinsmaya/SQLBot.git
synced 2026-11-08 09:17:06 +08:00
feat(Data Source): add Table relationship management
This commit is contained in:
@@ -3,6 +3,8 @@ import { request } from '@/utils/request'
|
||||
export const datasourceApi = {
|
||||
check: (data: any) => request.post('/datasource/check', data),
|
||||
check_by_id: (id: any) => request.get(`/datasource/check/${id}`),
|
||||
relationGet: (id: any) => request.post(`/table_relation/get/${id}`),
|
||||
relationSave: (dsId: any, data: any) => request.post(`/table_relation/save/${dsId}`, data),
|
||||
add: (data: any) => request.post('/datasource/add', data),
|
||||
list: () => request.get('/datasource/list'),
|
||||
update: (data: any) => request.post('/datasource/update', data),
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3.64022 7.5556C4.16283 6.83993 4.62541 5.57259 5.08687 3.73093C5.35032 2.6795 5.67072 2.22226 5.94868 2.22226C6.19414 2.22226 6.39312 2.02328 6.39312 1.77782C6.39312 1.53236 6.19414 1.33337 5.94868 1.33337C5.11915 1.33337 4.5776 2.10619 4.22463 3.51488C3.82889 5.09429 3.42651 6.20034 3.07384 6.81136C2.92269 6.71956 2.74527 6.66671 2.55551 6.66671H1.88884C1.33655 6.66671 0.88884 7.11442 0.88884 7.66671V8.33337C0.88884 8.88566 1.33655 9.33337 1.88884 9.33337H2.55551C2.72066 9.33337 2.87646 9.29334 3.01373 9.22244C3.33856 9.88614 3.69874 10.9577 4.05281 12.4189C4.40497 13.8723 4.94329 14.6667 5.77769 14.6667C6.02314 14.6667 6.22213 14.4677 6.22213 14.2223C6.22213 13.9768 6.02314 13.7778 5.77769 13.7778C5.5046 13.7778 5.18096 13.3002 4.9167 12.2096C4.49157 10.4551 4.06637 9.20697 3.59353 8.44449H6.4666C6.57706 8.44449 6.6666 8.35494 6.6666 8.24449V7.7556C6.6666 7.64514 6.57706 7.5556 6.4666 7.5556H3.64022Z"/>
|
||||
<path d="M7.99997 2.11115C7.99997 1.92706 8.14921 1.77782 8.3333 1.77782H14.7777C14.9618 1.77782 15.1111 1.92706 15.1111 2.11115V3.22226C15.1111 3.40636 14.9618 3.5556 14.7777 3.5556H8.3333C8.14921 3.5556 7.99997 3.40636 7.99997 3.22226V2.11115Z"/>
|
||||
<path d="M8.3333 7.11115C8.14921 7.11115 7.99997 7.26039 7.99997 7.44449V8.5556C7.99997 8.73969 8.14921 8.88893 8.3333 8.88893H14.7777C14.9618 8.88893 15.1111 8.73969 15.1111 8.5556V7.44449C15.1111 7.26039 14.9618 7.11115 14.7777 7.11115H8.3333Z"/>
|
||||
<path d="M7.99997 12.7778C7.99997 12.5937 8.14921 12.4445 8.3333 12.4445H14.7777C14.9618 12.4445 15.1111 12.5937 15.1111 12.7778V13.8889C15.1111 14.073 14.9618 14.2223 14.7777 14.2223H8.3333C8.14921 14.2223 7.99997 14.073 7.99997 13.8889V12.7778Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -7,6 +7,8 @@
|
||||
"AI Model Configuration": "AI Model Configuration"
|
||||
},
|
||||
"training": {
|
||||
"add_it_here": "Drag the table name on the left to add it here",
|
||||
"table_relationship_management": "Table relationship management",
|
||||
"system_anagement": "System Management",
|
||||
"data_training": "SQL Sample Lib",
|
||||
"problem_description": "Problem Description",
|
||||
@@ -669,4 +671,4 @@
|
||||
"setting_successfully": "Setting Successfully",
|
||||
"customize_theme_color": "Customize theme color"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,8 @@
|
||||
"AI Model Configuration": "模型配置"
|
||||
},
|
||||
"training": {
|
||||
"add_it_here": "拖拽左侧表名,添加到这里",
|
||||
"table_relationship_management": "表关系管理",
|
||||
"system_anagement": "系统管理",
|
||||
"data_training": "SQL 示例库",
|
||||
"problem_description": "问题描述",
|
||||
@@ -669,4 +671,4 @@
|
||||
"setting_successfully": "设置成功",
|
||||
"customize_theme_color": "自定义主题色"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -514,6 +514,10 @@ const scrollBottom = () => {
|
||||
if (!isTyping.value && !getRecommendQuestionsLoading.value) {
|
||||
clearInterval(scrollTime)
|
||||
}
|
||||
if (!chatListRef.value) {
|
||||
clearInterval(scrollTime)
|
||||
return
|
||||
}
|
||||
chatListRef.value!.setScrollTop(innerRef.value!.clientHeight)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ import EmptyBackground from '@/views/dashboard/common/EmptyBackground.vue'
|
||||
import edit from '@/assets/svg/icon_edit_outlined.svg'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import ParamsForm from './ParamsForm.vue'
|
||||
|
||||
import TableRelationship from '@/views/ds/TableRelationship.vue'
|
||||
import icon_mindnote_outlined from '@/assets/svg/icon_mindnote_outlined.svg'
|
||||
interface Table {
|
||||
name: string
|
||||
host: string
|
||||
@@ -54,6 +55,7 @@ const paramsFormRef = ref()
|
||||
const tableList = ref([] as any[])
|
||||
const loading = ref(false)
|
||||
const initLoading = ref(false)
|
||||
const activeRelationship = ref(false)
|
||||
const keywords = ref('')
|
||||
const tableListWithSearch = computed(() => {
|
||||
if (!keywords.value) return tableList.value
|
||||
@@ -66,13 +68,29 @@ const showNum = ref(100)
|
||||
const currentTable = ref<any>({})
|
||||
const ds = ref<any>({})
|
||||
const btnSelect = ref('d')
|
||||
|
||||
const isDrag = ref(false)
|
||||
const tableName = ref<any[]>([])
|
||||
const pageInfo = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
})
|
||||
const handleRelationship = () => {
|
||||
activeRelationship.value = !activeRelationship.value
|
||||
currentTable.value = {}
|
||||
}
|
||||
const singleDragStartD = (e: DragEvent, ele: any) => {
|
||||
isDrag.value = true
|
||||
e.dataTransfer!.setData('table', JSON.stringify(ele))
|
||||
}
|
||||
|
||||
const getTableName = (val: any) => {
|
||||
tableName.value = val
|
||||
}
|
||||
|
||||
const singleDragEnd = () => {
|
||||
isDrag.value = false
|
||||
}
|
||||
const handleSizeChange = (val: number) => {
|
||||
pageInfo.currentPage = 1
|
||||
pageInfo.pageSize = val
|
||||
@@ -119,6 +137,7 @@ const handleSelectTableList = () => {
|
||||
}
|
||||
|
||||
const clickTable = (table: any) => {
|
||||
if (activeRelationship.value) return
|
||||
loading.value = true
|
||||
currentTable.value = table
|
||||
fieldList.value = []
|
||||
@@ -290,8 +309,14 @@ const btnSelectClick = (val: any) => {
|
||||
<div
|
||||
v-for="ele in tableListWithSearch"
|
||||
:key="ele.table_name"
|
||||
:draggable="activeRelationship && !tableName.includes(ele.id)"
|
||||
class="model"
|
||||
:class="currentTable.table_name === ele.table_name && 'isActive'"
|
||||
@dragstart="($event: any) => singleDragStartD($event, ele)"
|
||||
@dragend="singleDragEnd"
|
||||
:class="[
|
||||
currentTable.table_name === ele.table_name && 'isActive',
|
||||
tableName.includes(ele.id) && activeRelationship && 'disabled-table',
|
||||
]"
|
||||
:title="ele.table_name"
|
||||
@click="clickTable(ele)"
|
||||
>
|
||||
@@ -318,9 +343,32 @@ const btnSelectClick = (val: any) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-relationship">
|
||||
<div @click="handleRelationship" :class="activeRelationship && 'active'" class="btn">
|
||||
<el-icon size="16">
|
||||
<icon_mindnote_outlined></icon_mindnote_outlined>
|
||||
</el-icon>
|
||||
{{ t('training.table_relationship_management') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="currentTable.table_name" v-loading="loading" class="info-table">
|
||||
<div v-if="activeRelationship" class="relationship-content">
|
||||
<div class="title">{{ t('training.table_relationship_management') }}</div>
|
||||
<div class="content">
|
||||
<TableRelationship
|
||||
@getTableName="getTableName"
|
||||
:dragging="isDrag"
|
||||
:id="info.id"
|
||||
></TableRelationship>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="currentTable.table_name && !activeRelationship"
|
||||
v-loading="loading"
|
||||
class="info-table"
|
||||
>
|
||||
<div class="table-name">
|
||||
<div class="name">{{ currentTable.table_name }}</div>
|
||||
<div class="notes">
|
||||
@@ -336,6 +384,7 @@ const btnSelectClick = (val: any) => {
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-content">
|
||||
<div class="btn-select">
|
||||
<el-button
|
||||
@@ -532,6 +581,46 @@ const btnSelectClick = (val: any) => {
|
||||
padding: 8px 16px;
|
||||
height: 100%;
|
||||
border-right: 1px solid #1f232926;
|
||||
.table-relationship {
|
||||
height: 56px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
width: calc(100% + 32px);
|
||||
position: absolute;
|
||||
left: -16px;
|
||||
background-color: #1f232926;
|
||||
top: 0;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 248px;
|
||||
height: 32px;
|
||||
cursor: pointer;
|
||||
border-radius: 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 8px;
|
||||
.ed-icon {
|
||||
color: #646a73;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: var(--ed-color-primary);
|
||||
.ed-icon {
|
||||
color: var(--ed-color-primary);
|
||||
}
|
||||
background-color: var(--ed-color-primary-1a);
|
||||
}
|
||||
}
|
||||
}
|
||||
.select-table_top {
|
||||
height: 40px;
|
||||
display: flex;
|
||||
@@ -551,7 +640,7 @@ const btnSelectClick = (val: any) => {
|
||||
}
|
||||
|
||||
.list-content {
|
||||
height: calc(100% - 100px);
|
||||
height: calc(100% - 156px);
|
||||
.no-result {
|
||||
margin-top: 72px;
|
||||
font-weight: 400;
|
||||
@@ -569,6 +658,12 @@ const btnSelectClick = (val: any) => {
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&.disabled-table {
|
||||
background: #dee0e3 !important;
|
||||
color: #646a73;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-left: 8px;
|
||||
font-weight: 500;
|
||||
@@ -604,6 +699,27 @@ const btnSelectClick = (val: any) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
.relationship-content {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: calc(100% - 280px);
|
||||
height: 100%;
|
||||
|
||||
.content {
|
||||
height: calc(100% - 56px);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 56px;
|
||||
padding-left: 24px;
|
||||
line-height: 56px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid #1f232926;
|
||||
}
|
||||
}
|
||||
.info-table {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
|
||||
@@ -0,0 +1,404 @@
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onBeforeUnmount, ref, nextTick } from 'vue'
|
||||
import { datasourceApi } from '@/api/datasource'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { Graph, Cell, Shape } from '@antv/x6'
|
||||
import type { AnyColumn } from 'element-plus-secondary/es/components/table-v2/src/common.mjs'
|
||||
|
||||
const LINE_HEIGHT = 36
|
||||
const NODE_WIDTH = 180
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
id: string
|
||||
dragging: boolean
|
||||
}>(),
|
||||
{
|
||||
id: '',
|
||||
dragging: false,
|
||||
}
|
||||
)
|
||||
|
||||
const emits = defineEmits(['getTableName'])
|
||||
|
||||
const { t } = useI18n()
|
||||
const loading = ref(false)
|
||||
|
||||
const nodeIds = ref<any[]>([])
|
||||
|
||||
const cells = ref<Cell[]>([])
|
||||
const edgeOPtion = {
|
||||
tools: [
|
||||
{
|
||||
name: 'button-remove', // 工具名称
|
||||
args: { x: 20, y: 20 }, // 工具对应的参数
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
line: {
|
||||
stroke: '#DEE0E3',
|
||||
strokeWidth: 1,
|
||||
},
|
||||
},
|
||||
}
|
||||
let graph: any
|
||||
|
||||
const initGraph = () => {
|
||||
Graph.registerPortLayout(
|
||||
'erPortPosition',
|
||||
(portsPositionArgs) => {
|
||||
return portsPositionArgs.map((_, index) => {
|
||||
return {
|
||||
position: {
|
||||
x: 0,
|
||||
y: (index + 1) * LINE_HEIGHT,
|
||||
},
|
||||
angle: 0,
|
||||
}
|
||||
})
|
||||
},
|
||||
true
|
||||
)
|
||||
|
||||
Graph.registerNode(
|
||||
'er-rect',
|
||||
{
|
||||
inherit: 'rect',
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'body',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'label',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
rect: {
|
||||
strokeWidth: 1,
|
||||
stroke: '#F5F6F7',
|
||||
fill: '#F5F6F7',
|
||||
},
|
||||
label: {
|
||||
fill: '#1F2329',
|
||||
fontSize: 14,
|
||||
},
|
||||
},
|
||||
ports: {
|
||||
groups: {
|
||||
list: {
|
||||
markup: [
|
||||
{
|
||||
tagName: 'rect',
|
||||
selector: 'portBody',
|
||||
},
|
||||
{
|
||||
tagName: 'text',
|
||||
selector: 'portNameLabel',
|
||||
},
|
||||
],
|
||||
attrs: {
|
||||
portBody: {
|
||||
width: NODE_WIDTH,
|
||||
height: LINE_HEIGHT,
|
||||
strokeWidth: 1,
|
||||
stroke: '#1F232926',
|
||||
fill: '#ffffff',
|
||||
magnet: true,
|
||||
},
|
||||
portNameLabel: {
|
||||
ref: 'portBody',
|
||||
refX: 12,
|
||||
refY: 8,
|
||||
fontSize: 14,
|
||||
textAnchor: 'left',
|
||||
textWrap: {
|
||||
width: 150,
|
||||
height: 24,
|
||||
ellipsis: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
position: 'erPortPosition',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
true
|
||||
)
|
||||
graph = new Graph({
|
||||
mousewheel: {
|
||||
enabled: true,
|
||||
modifiers: ['ctrl', 'meta'],
|
||||
},
|
||||
container: document.getElementById('container')!,
|
||||
autoResize: true,
|
||||
connecting: {
|
||||
allowBlank: false,
|
||||
router: {
|
||||
name: 'er',
|
||||
args: {
|
||||
offset: 25,
|
||||
direction: 'H',
|
||||
},
|
||||
},
|
||||
validateEdge({ edge }: any) {
|
||||
const obj = edge.store.data
|
||||
if (!obj.target.port || obj.target.cell === obj.source.cell) return false
|
||||
return true
|
||||
},
|
||||
createEdge() {
|
||||
return new Shape.Edge(edgeOPtion)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
graph.on('edge:mouseenter', ({ e }: any) => {
|
||||
Array.from(document.querySelectorAll('.x6-edge-tool')).forEach((ele: any) => {
|
||||
if (ele.dataset.cellId === e.target.parentNode.dataset.cellId) {
|
||||
ele.style.display = 'block'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
graph.on('edge:mouseleave', ({ e }: any) => {
|
||||
Array.from(document.querySelectorAll('.x6-edge-tool')).forEach((ele: any) => {
|
||||
if (ele.dataset.cellId === e.target.parentNode.dataset.cellId) {
|
||||
ele.style.display = 'none'
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
graph.on('node:mouseenter', ({ node }: any) => {
|
||||
node.addTools({
|
||||
name: 'button',
|
||||
args: {
|
||||
markup: [
|
||||
{
|
||||
tagName: 'circle',
|
||||
selector: 'button',
|
||||
attrs: {
|
||||
r: 7,
|
||||
cursor: 'pointer',
|
||||
},
|
||||
},
|
||||
{
|
||||
tagName: 'path',
|
||||
selector: 'icon',
|
||||
attrs: {
|
||||
d: 'M -3 -3 3 3 M -3 3 3 -3',
|
||||
stroke: 'white',
|
||||
'stroke-width': 2,
|
||||
cursor: 'pointer',
|
||||
},
|
||||
},
|
||||
],
|
||||
x: 0,
|
||||
y: 0,
|
||||
offset: { x: 165, y: 18 },
|
||||
onClick({ view }: any) {
|
||||
graph.removeNode(view.cell.id)
|
||||
nodeIds.value = nodeIds.value.filter((ele) => ele !== view.cell.id)
|
||||
if (!nodeIds.value.length) {
|
||||
graph.dispose()
|
||||
graph = null
|
||||
}
|
||||
emits('getTableName', [...nodeIds.value])
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
// 鼠标移开时删除按钮
|
||||
graph.on('node:mouseleave', ({ node }: any) => {
|
||||
node.removeTools() // 删除所有的工具
|
||||
})
|
||||
}
|
||||
|
||||
const getTableData = () => {
|
||||
loading.value = true
|
||||
datasourceApi
|
||||
.relationGet(props.id)
|
||||
.then((data: any) => {
|
||||
nodeIds.value = data.filter((ele: any) => ele.shape === 'er-rect').map((ele: any) => ele.id)
|
||||
nextTick(() => {
|
||||
if (!graph) {
|
||||
initGraph()
|
||||
}
|
||||
data.forEach((item: any) => {
|
||||
if (item.shape === 'edge') {
|
||||
cells.value.push(graph.createEdge({ ...item, ...edgeOPtion }))
|
||||
} else {
|
||||
console.log(item)
|
||||
|
||||
cells.value.push(
|
||||
graph.createNode({
|
||||
...item,
|
||||
attrs: {
|
||||
label: {
|
||||
text: item.attrs.text.text,
|
||||
textAnchor: 'left',
|
||||
refX: 10,
|
||||
textWrap: {
|
||||
width: 140,
|
||||
height: 24,
|
||||
ellipsis: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
height: LINE_HEIGHT,
|
||||
width: NODE_WIDTH,
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
graph.resetCells(cells.value)
|
||||
graph.zoomToFit({ padding: 10, maxScale: 1 })
|
||||
emits('getTableName', [...nodeIds.value])
|
||||
})
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
getTableData()
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
graph = null
|
||||
})
|
||||
const dragover = () => {
|
||||
// do
|
||||
}
|
||||
|
||||
const addNode = (node: any) => {
|
||||
if (!graph) {
|
||||
initGraph()
|
||||
}
|
||||
graph.addNode(graph.createNode({ ...node, height: LINE_HEIGHT, width: NODE_WIDTH }))
|
||||
}
|
||||
|
||||
const clickTable = (table: any) => {
|
||||
loading.value = true
|
||||
datasourceApi
|
||||
.fieldList(table.id)
|
||||
.then((res: AnyColumn) => {
|
||||
const node = {
|
||||
id: table.id,
|
||||
shape: 'er-rect',
|
||||
label: table.table_name,
|
||||
width: 150,
|
||||
height: 24,
|
||||
position: {
|
||||
x: table.x,
|
||||
y: table.y,
|
||||
},
|
||||
ports: res.map((ele: any) => {
|
||||
return {
|
||||
id: ele.id,
|
||||
group: 'list',
|
||||
attrs: {
|
||||
portNameLabel: {
|
||||
text: ele.field_name,
|
||||
},
|
||||
portTypeLabel: {
|
||||
text: ele.field_type,
|
||||
},
|
||||
},
|
||||
}
|
||||
}),
|
||||
}
|
||||
nodeIds.value = [...nodeIds.value, table.id]
|
||||
nextTick(() => {
|
||||
addNode(node)
|
||||
})
|
||||
emits('getTableName', [...nodeIds.value])
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
const drop = (e: any) => {
|
||||
const obj = JSON.parse(e.dataTransfer.getData('table') || '{}')
|
||||
if (!obj.id) return
|
||||
clickTable({ ...obj, x: e.layerX, y: e.layerY })
|
||||
}
|
||||
const save = () => {
|
||||
datasourceApi.relationSave(props.id, graph.toJSON().cells).then(() => {
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: t('common.save_success'),
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-loading="loading" v-if="!nodeIds.length" class="relationship-empty">
|
||||
{{ t('training.add_it_here') }}
|
||||
</div>
|
||||
<div v-loading="loading" v-else id="container"></div>
|
||||
<div
|
||||
@dragover.prevent.stop="dragover"
|
||||
@drop.prevent.stop="drop"
|
||||
v-show="dragging"
|
||||
class="drag-mask"
|
||||
></div>
|
||||
<div class="save-btn">
|
||||
<el-button type="primary" v-if="nodeIds.length" @click="save">
|
||||
{{ t('common.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.save-btn {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
}
|
||||
.drag-mask {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 56px;
|
||||
z-index: 10;
|
||||
}
|
||||
.relationship-empty {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 16px;
|
||||
}
|
||||
#container {
|
||||
font-size: 14px;
|
||||
user-select: text;
|
||||
overflow: hidden;
|
||||
outline: none;
|
||||
touch-action: none;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
min-width: 400px;
|
||||
min-height: 600px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
:deep(.x6-edge-tool) {
|
||||
display: none;
|
||||
|
||||
circle {
|
||||
fill: var(--ed-color-primary) !important;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.x6-node-tool) {
|
||||
circle {
|
||||
fill: var(--ed-color-primary) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user