Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
csbr-daop
/
fe-data-trusted-space
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
8957880b
authored
2025-06-24 14:34:39 +0800
by
lihua
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
查看关系网接口联调
1 parent
a4f209d4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
297 additions
and
95 deletions
src/components/LineageGraph/index.vue
src/components/RelationNetwork/index.vue
src/router/modules/dataMeta.ts
src/views/data_meta/components/Sankey.vue
src/views/data_meta/standard-query-view.vue
src/views/data_meta/standard-query.vue
src/views/data_meta/standard.vue
src/components/LineageGraph/index.vue
View file @
8957880
...
...
@@ -741,6 +741,7 @@ onMounted(() => {
toolRef
.
value
.
isFull
=
true
}
},
500
)
return
;
}
const
container
:
any
=
containerRef
.
value
;
const
width
=
container
.
clientWidth
;
...
...
src/components/RelationNetwork/index.vue
View file @
8957880
This diff is collapsed.
Click to expand it.
src/router/modules/dataMeta.ts
View file @
8957880
...
...
@@ -263,6 +263,22 @@ const routes: RouteRecordRaw[] = [
}
},
{
path
:
'standard-query-view'
,
name
:
'metadataStandardQueryView'
,
component
:
()
=>
import
(
'@/views/data_meta/standard-query-view.vue'
),
meta
:
{
title
:
'元数据标准查看'
,
breadcrumb
:
false
,
cache
:
true
,
activeMenu
:
'/data-meta/metadata-standard'
},
beforeEnter
:
(
to
,
from
)
=>
{
if
(
to
.
query
.
name
)
{
to
.
meta
.
title
=
`元数据标准查看-
${
to
.
query
.
name
}
`
;
}
}
},
{
path
:
'standard-codetable'
,
name
:
'metadataStandardCodetable'
,
component
:
()
=>
import
(
'@/views/data_meta/standard-codetable.vue'
),
...
...
src/views/data_meta/components/Sankey.vue
View file @
8957880
...
...
@@ -80,15 +80,23 @@ const containerRef = ref();
const
setChartsOption
=
()
=>
{
let
option
=
{
tooltip
:
{
trigger
:
'item'
trigger
:
'item'
,
formatter
:
(
params
)
=>
{
if
(
params
.
data
.
name
)
{
return
null
;
}
return
params
.
data
.
source
+
' --> '
+
params
.
data
.
target
}
},
color
:
[
"#3DBCBE"
,
"#6b67d1"
,
"#7BBCE0"
,
"#2B8EF3"
,
"#51dca2"
,
"#E19D46"
],
series
:
[
{
type
:
'sankey'
,
top
:
80
,
bottom
:
40
,
left
:
50
,
right
:
50
,
draggable
:
false
,
left
:
40
,
right
:
80
,
data
:
props
.
names
,
links
:
props
.
treeData
,
lineStyle
:
{
...
...
src/views/data_meta/standard-query-view.vue
0 → 100644
View file @
8957880
<route
lang=
"yaml"
>
name: metadataStandardQueryView
</route>
<
template
>
<div
class=
"main_wrap"
v-loading=
"graphDataLoading"
>
<div
className=
'g6-component-topbar'
>
<graphTopbar
ref=
"topBarRef"
@
displaySwitchChange=
"displaySwitchChange"
:isGraphDisplay=
"isGraphDisplay"
/>
</div>
<RelationNetwork
v-show=
"graphTreeData?.guid && isGraphDisplay"
ref=
"relationNetworkRef"
:tree-data=
"graphTreeData"
:noContextMenu=
"true"
@
nodeItemClick=
"handleNodeItemClick"
>
</RelationNetwork>
<Sankey
v-show=
"!isGraphDisplay && (sankeyNames?.length || sankeyDataLoading)"
v-loading=
"sankeyDataLoading"
:tree-data=
"sankeyData"
:names=
"sankeyNames"
>
</Sankey>
<div
v-show=
"(isGraphDisplay ? !graphTreeData?.guid : (!sankeyDataLoading && !sankeyNames?.length))"
class=
"main-placeholder"
>
<img
src=
"../../assets/images/no-data.png"
:style=
"
{ width: '96px', height: '96px' }" />
<div
class=
"empty-text"
>
暂无数据
</div>
</div>
</div>
</
template
>
<
script
lang=
"ts"
setup
name=
"metadataStandardQueryView"
>
import
{
getMetaStandardField
,
getSankeyData
,
getMetaStandardTreeList
}
from
'@/api/modules/dataMetaService'
;
import
Sankey
from
'./components/Sankey.vue'
;
import
{
ElMessage
}
from
'element-plus'
;
const
router
=
useRouter
();
const
route
=
useRoute
()
const
metaGuid
=
ref
(
route
.
query
.
guid
);
const
{
proxy
}
=
getCurrentInstance
()
as
any
;
const
relationNetworkRef
=
ref
();
const
graphDataLoading
=
ref
(
false
);
/** 关系网树形数据 */
const
graphTreeData
:
any
=
ref
({});
onBeforeUnmount
(()
=>
{
relationNetworkRef
.
value
.
destroy
();
})
const
sankeyDataLoading
=
ref
(
false
);
const
sankeyData
:
any
=
ref
([]);
const
sankeyNames
:
any
=
ref
([]);
const
isGraphDisplay
=
ref
(
true
);
const
displaySwitchChange
=
(
val
)
=>
{
if
(
val
==
isGraphDisplay
.
value
)
{
return
;
}
isGraphDisplay
.
value
=
val
;
if
(
!
val
)
{
getSankeyDataList
();
}
}
const
getSankeyDataList
=
()
=>
{
sankeyDataLoading
.
value
=
true
;
getSankeyData
(
metaGuid
.
value
).
then
((
res
:
any
)
=>
{
sankeyDataLoading
.
value
=
false
;
if
(
res
?.
code
==
proxy
.
$passCode
)
{
sankeyData
.
value
=
res
.
data
?.
links
||
[];
sankeyNames
.
value
=
res
.
data
?.
data
||
[];
}
else
{
ElMessage
.
error
(
res
.
msg
);
}
})
}
const
handleNodeItemClick
=
(
graph
,
nodeItem
)
=>
{
const
nodeId
=
nodeItem
.
get
(
'id'
);
const
parentData
=
graph
.
findDataById
(
nodeId
);
if
(
!
parentData
.
children
)
{
parentData
.
children
=
[];
}
if
(
parentData
.
isHaveData
==
'N'
)
{
ElMessage
.
warning
(
'没有可展开的下级字段'
);
return
;
}
graphDataLoading
.
value
=
true
;
getMetaStandardField
(
nodeId
).
then
((
res
:
any
)
=>
{
graphDataLoading
.
value
=
false
;
if
(
res
?.
code
==
proxy
.
$passCode
)
{
const
data
=
res
.
data
||
[];
parentData
.
children
=
[];
if
(
!
data
?.
length
)
{
parentData
.
isHaveData
=
'N'
;
ElMessage
.
warning
(
'没有可展开的下级字段'
);
return
;
}
data
.
forEach
(
d
=>
{
parentData
.
children
.
push
(
d
);
})
parentData
.
collapsed
=
false
;
setTimeout
(()
=>
{
parentData
.
isLoading
=
false
;
graph
.
setMaxZoom
(
1
);
graph
.
changeData
(
graphTreeData
.
value
);
graph
.
setMaxZoom
(
5
);
},
100
);
}
else
{
parentData
.
isLoading
=
false
;
ElMessage
.
error
(
res
.
msg
);
}
})
}
onBeforeMount
(()
=>
{
graphDataLoading
.
value
=
true
getMetaStandardTreeList
(
metaGuid
.
value
).
then
((
res
:
any
)
=>
{
graphDataLoading
.
value
=
false
;
if
(
res
?.
code
==
proxy
.
$passCode
)
{
const
data
=
res
.
data
||
[];
graphTreeData
.
value
=
data
?.[
0
]
||
{};
}
else
{
ElMessage
.
error
(
res
.
msg
);
}
})
})
</
script
>
<
style
lang=
"scss"
scoped
>
.main_wrap
{
height
:
100%
;
width
:
100%
;
position
:
relative
;
:deep(.canvas-wrapper)
{
background-color
:
#f7f7f9
;
}
.main-placeholder
{
height
:
100%
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
flex-direction
:
column
;
.empty-text
{
font-size
:
14px
;
color
:
#b2b2b2
;
}
}
}
.g6-component-topbar
{
position
:
absolute
;
left
:
24px
;
bottom
:
unset
;
top
:
14px
;
padding
:
0
;
text-align
:
center
;
z-index
:
999
;
}
</
style
>
\ No newline at end of file
src/views/data_meta/standard-query.vue
View file @
8957880
...
...
@@ -9,16 +9,17 @@ import Sankey from './components/Sankey.vue';
import
Tree
from
'@/components/Tree/index.vue'
;
import
RelationNetwork
from
'@/components/RelationNetwork/index.vue'
;
import
{
getMetaStandardTreeList
,
getMetaStandardField
,
getSankeyData
}
from
'@/api/modules/dataMetaService'
;
import
{
useRouter
,
useRoute
}
from
"vue-router"
;
import
useDataMetaStore
from
"@/store/modules/dataMeta"
import
{
cloneDeep
}
from
'lodash-es'
;
const
router
=
useRouter
();
const
route
=
useRoute
()
const
switchGraphDisplay
=
ref
(
true
);
//true表示关系网,false表示桑基图
const
{
proxy
}
=
getCurrentInstance
()
as
any
;
const
relationNetworkRef
=
ref
();
...
...
@@ -27,14 +28,14 @@ const treeInfo = ref({
id
:
"data-meta-standard-tree"
,
filter
:
true
,
queryValue
:
""
,
queryPlaceholder
:
"
输入库/表名称
搜索"
,
queryPlaceholder
:
"
请输入关键字
搜索"
,
props
:
{
label
:
"
n
ame"
,
label
:
"
standardN
ame"
,
value
:
"guid"
,
isLeaf
:
"isLeaf"
,
},
nodeKey
:
'guid'
,
expandedKey
:
[
'1'
],
expandedKey
:
[],
currentNodeKey
:
''
,
expandOnNodeClick
:
false
,
data
:
<
any
>
[],
...
...
@@ -44,51 +45,20 @@ const treeInfo = ref({
/** 获取左侧树数据. */
const
getTreeData
=
async
()
=>
{
treeInfo
.
value
.
loading
=
true
// let params = {}
// const res: any = await getMetaTreeData(params)
// if (res.code == proxy.$passCode) {
// const data = res.data || [];
// let treeData: any = Object.keys(data).length ? [data] : [];
// treeInfo.value.data = treeData;
// allTreeData.value = treeData;
// if (treeData.length) {
// treeInfo.value.currentNodeKey = treeData[0].guid;
// treeInfo.value.expandedKey = <any>[treeData[0].guid];
// }
// } else {
// ElMessage.error(res.msg);
// }
treeInfo
.
value
.
data
=
[{
guid
:
'1'
,
name
:
'第一级1'
,
children
:
[{
guid
:
'1-1'
,
name
:
'第二级1-1'
,
children
:
[{
guid
:
'1-1-1'
,
name
:
'第三级1-1-1'
}]
},
{
guid
:
'1-2'
,
name
:
'第二级1-2'
},
{
guid
:
'1-3'
,
name
:
'第二级1-3'
}]
},
{
guid
:
'2'
,
name
:
'第一级2'
,
children
:
[{
guid
:
'2-1'
,
name
:
'第二级1-1'
},
{
guid
:
'2-2'
,
name
:
'第二级1-2'
}]
}];
treeInfo
.
value
.
loading
=
false
treeInfo
.
value
.
currentNodeKey
=
'1'
;
nodeClick
(
treeInfo
.
value
.
data
[
0
])
getMetaStandardTreeList
(
''
).
then
((
res
:
any
)
=>
{
treeInfo
.
value
.
loading
=
false
;
if
(
res
?.
code
==
proxy
.
$passCode
)
{
const
data
=
res
.
data
||
[];
treeInfo
.
value
.
data
=
data
;
if
(
data
.
length
)
{
treeInfo
.
value
.
currentNodeKey
=
data
[
0
].
guid
;
treeInfo
.
value
.
expandedKey
=
<
any
>
[
data
[
0
].
guid
];
nodeClick
(
treeInfo
.
value
.
data
[
0
])
}
}
else
{
ElMessage
.
error
(
res
.
msg
);
}
})
}
/** 左侧树的的组件引用. */
const
treeInfoRef
=
ref
();
...
...
@@ -98,22 +68,18 @@ const lastClickNode: any = ref({});
const
treeDataLoading
=
ref
(
false
);
/** 数据血缘关系图组件 */
const
lineageGraph
:
any
=
ref
();
/** 点击左侧树节点,更新对应的血缘关系图. */
const
nodeClick
=
(
data
)
=>
{
console
.
log
(
data
);
const
ele
=
<
HTMLElement
>
document
.
querySelector
(
".g6-component-contextmenu"
)
if
(
ele
)
{
ele
.
style
.
display
=
"none"
}
nextTick
(()
=>
{
lineageGraph
.
value
?.
tooltip1
.
hide
()
})
treeInfo
.
value
.
currentNodeKey
=
data
.
guid
;
treeInfo
.
value
.
expandedKey
=
<
any
>
[
data
.
guid
];
lastClickNode
.
value
=
data
;
lastClickNode
.
value
=
cloneDeep
(
data
);
if
(
!
isGraphDisplay
.
value
)
{
getSankeyDataList
();
}
}
/** 选中树节点后自动滚动到可视范围内. */
...
...
@@ -145,7 +111,6 @@ const processRouter = () => {
treeInfo
.
value
.
expandedKey
=
<
any
>
[
databaseGuid
,
guid
];
lastClickNode
.
value
=
{
guid
:
guid
,
tableName
,
databaseName
,
type
:
3
,
databaseChName
};
scrollToNode
(
guid
);
switchGraphDisplay
.
value
=
isFL
;
// if (isFL) {
// getAllTableFieldLineageMap();
// } else {
...
...
@@ -156,20 +121,45 @@ const processRouter = () => {
}
onActivated
(()
=>
{
processRouter
();
//
processRouter();
});
onBeforeMount
(
async
()
=>
{
await
getTreeData
()
processRouter
();
//
processRouter();
})
onMounted
(()
=>
{
})
const
sankeyDataLoading
=
ref
(
false
);
const
sankeyData
:
any
=
ref
([]);
const
sankeyNames
:
any
=
ref
([]);
const
isGraphDisplay
=
ref
(
true
);
const
displaySwitchChange
=
(
val
)
=>
{
if
(
val
==
isGraphDisplay
.
value
)
{
return
;
}
isGraphDisplay
.
value
=
val
;
if
(
!
val
)
{
getSankeyDataList
();
}
}
const
getSankeyDataList
=
()
=>
{
sankeyDataLoading
.
value
=
true
;
getSankeyData
(
lastClickNode
.
value
.
guid
).
then
((
res
:
any
)
=>
{
sankeyDataLoading
.
value
=
false
;
if
(
res
?.
code
==
proxy
.
$passCode
)
{
sankeyData
.
value
=
res
.
data
?.
links
||
[];
sankeyNames
.
value
=
res
.
data
?.
data
||
[];
}
else
{
ElMessage
.
error
(
res
.
msg
);
}
})
}
const
handleNodeItemClick
=
(
graph
,
nodeItem
)
=>
{
...
...
@@ -178,35 +168,41 @@ const handleNodeItemClick = (graph, nodeItem) => {
if
(
!
parentData
.
children
)
{
parentData
.
children
=
[];
}
if
(
parentData
.
noData
)
{
ElMessage
.
warning
(
'没有可展开的下级字段'
);
return
;
}
treeDataLoading
.
value
=
true
;
let
childData
=
[{
guid
:
'33'
,
isField
:
true
,
name
:
'字段1'
},
{
guid
:
'44'
,
isField
:
true
,
name
:
'字段2字段2字段2字段2字段2字段2字段2字段2字段2xx2字段22字段22字段22字段22字段22字段2'
},
{
guid
:
'55'
,
isField
:
true
,
name
:
'字段3'
}]
// parentData.collapsed = true;
// nodeItem.getModel().collapsed = true;
parentData
.
children
=
childData
;
setTimeout
(()
=>
{
getMetaStandardField
(
nodeId
).
then
((
res
:
any
)
=>
{
treeDataLoading
.
value
=
false
;
graph
.
changeData
();
// parentData.collapsed = true;
// graph.updateChildren(childData, parentData.id);
// graph.changeData(lastClickNode.value);
//graph.data(lastClickNode.value);
},
2000
)
if
(
res
?.
code
==
proxy
.
$passCode
)
{
const
data
=
res
.
data
||
[];
parentData
.
children
=
[];
if
(
!
data
?.
length
)
{
parentData
.
noData
=
true
;
ElMessage
.
warning
(
'没有可展开的下级字段'
);
return
;
}
data
.
forEach
(
d
=>
{
parentData
.
children
.
push
(
d
);
})
parentData
.
collapsed
=
false
;
setTimeout
(()
=>
{
parentData
.
isLoading
=
false
;
graph
.
setMaxZoom
(
1
);
graph
.
changeData
(
lastClickNode
.
value
);
graph
.
setMaxZoom
(
5
);
},
100
);
}
else
{
parentData
.
isLoading
=
false
;
ElMessage
.
error
(
res
.
msg
);
}
})
}
const
handleContextMenu
=
(
nodeData
)
=>
{
//TODO,新建引用数据集
window
.
open
(
''
);
}
onBeforeUnmount
(()
=>
{
...
...
@@ -218,21 +214,23 @@ onBeforeUnmount(() => {
<
template
>
<div
class=
"container_wrap full flex"
>
<div
class=
"aside_wrap"
>
<div
class=
"aside_title"
>
数据库目录
列表
</div>
<div
class=
"aside_title"
>
元数据标准
列表
</div>
<Tree
ref=
"treeInfoRef"
:treeInfo=
"treeInfo"
@
nodeClick=
"nodeClick"
/>
</div>
<div
class=
"main_wrap"
>
<div
className=
'g6-component-topbar'
>
<graphTopbar
ref=
"topBarRef"
@
displaySwitchChange=
"displaySwitchChange"
:isGraphDisplay=
"isGraphDisplay"
/>
</div>
<RelationNetwork
v-show=
"isGraphDisplay"
ref=
"relationNetworkRef"
:tree-data=
"lastClickNode"
v-loading=
"treeDataLoading"
@
nodeItemClick=
"handleNodeItemClick"
@
contextMenu=
"handleContextMenu"
>
<RelationNetwork
v-show=
"lastClickNode?.guid && isGraphDisplay"
ref=
"relationNetworkRef"
:tree-data=
"lastClickNode"
v-loading=
"treeDataLoading"
@
nodeItemClick=
"handleNodeItemClick"
@
contextMenu=
"handleContextMenu"
>
</RelationNetwork>
<Sankey
v-show=
"!isGraphDisplay"
></Sankey>
<!--
<div
v-show=
"lastClickNode && lastClickNode?.type !== 3 && lastClickNode?.type !== 4"
class=
"main-placeholder"
>
<Sankey
v-show=
"lastClickNode?.guid && !isGraphDisplay && (sankeyNames?.length || sankeyDataLoading)"
v-loading=
"sankeyDataLoading"
:tree-data=
"sankeyData"
:names=
"sankeyNames"
>
</Sankey>
<div
v-show=
"!lastClickNode?.guid && !treeInfo.data?.length || (!isGraphDisplay && !sankeyDataLoading && !sankeyNames?.length)"
class=
"main-placeholder"
>
<img
src=
"../../assets/images/no-data.png"
:style=
"
{ width: '96px', height: '96px' }" />
<div
class=
"empty-text"
>
暂无
标准
数据
</div>
</div>
-->
<div
class=
"empty-text"
>
暂无数据
</div>
</div>
</div>
</div>
</
template
>
...
...
src/views/data_meta/standard.vue
View file @
8957880
...
...
@@ -416,6 +416,17 @@ function exportData () {
onBeforeMount
(()
=>
{
getTree
()
})
const
viewGraph
=
()
=>
{
router
.
push
({
name
:
'metadataStandardQueryView'
,
query
:
{
guid
:
treeInfo
.
value
.
currentObj
?.
guid
,
name
:
treeInfo
.
value
.
currentObj
?.
standardName
,
}
});
}
</
script
>
<
template
>
...
...
Write
Preview
Styling with
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment