6f2a062d by lihua

查看关系网接口联调

1 parent cecd64f1
...@@ -741,6 +741,7 @@ onMounted(() => { ...@@ -741,6 +741,7 @@ onMounted(() => {
741 toolRef.value.isFull = true 741 toolRef.value.isFull = true
742 } 742 }
743 }, 500) 743 }, 500)
744 return;
744 } 745 }
745 const container: any = containerRef.value; 746 const container: any = containerRef.value;
746 const width = container.clientWidth; 747 const width = container.clientWidth;
......
...@@ -262,6 +262,22 @@ const routes: RouteRecordRaw[] = [ ...@@ -262,6 +262,22 @@ const routes: RouteRecordRaw[] = [
262 } 262 }
263 }, 263 },
264 { 264 {
265 path: 'standard-query-view',
266 name: 'metadataStandardQueryView',
267 component: () => import('@/views/data_meta/standard-query-view.vue'),
268 meta: {
269 title: '元数据标准查看',
270 breadcrumb: false,
271 cache: true,
272 activeMenu: '/data-meta/metadata-standard'
273 },
274 beforeEnter: (to, from) => {
275 if (to.query.name) {
276 to.meta.title = `元数据标准查看-${to.query.name}`;
277 }
278 }
279 },
280 {
265 path: 'standard-codetable', 281 path: 'standard-codetable',
266 name: 'metadataStandardCodetable', 282 name: 'metadataStandardCodetable',
267 component: () => import('@/views/data_meta/standard-codetable.vue'), 283 component: () => import('@/views/data_meta/standard-codetable.vue'),
......
...@@ -80,15 +80,23 @@ const containerRef = ref(); ...@@ -80,15 +80,23 @@ const containerRef = ref();
80 const setChartsOption = () => { 80 const setChartsOption = () => {
81 let option = { 81 let option = {
82 tooltip: { 82 tooltip: {
83 trigger: 'item' 83 trigger: 'item',
84 formatter: (params) => {
85 if (params.data.name) {
86 return null;
87 }
88 return params.data.source + ' --> ' + params.data.target
89 }
84 }, 90 },
91 color: ["#3DBCBE", "#6b67d1", "#7BBCE0", "#2B8EF3", "#51dca2", "#E19D46"],
85 series: [ 92 series: [
86 { 93 {
87 type: 'sankey', 94 type: 'sankey',
88 top: 80, 95 top: 80,
89 bottom: 40, 96 bottom: 40,
90 left: 50, 97 draggable: false,
91 right: 50, 98 left: 40,
99 right: 80,
92 data: props.names, 100 data: props.names,
93 links: props.treeData, 101 links: props.treeData,
94 lineStyle: { 102 lineStyle: {
......
1 <route lang="yaml">
2 name: metadataStandardQueryView
3 </route>
4
5 <template>
6 <div class="main_wrap" v-loading="graphDataLoading">
7 <div className='g6-component-topbar'>
8 <graphTopbar ref="topBarRef" @displaySwitchChange="displaySwitchChange" :isGraphDisplay="isGraphDisplay" />
9 </div>
10 <RelationNetwork v-show="graphTreeData?.guid && isGraphDisplay" ref="relationNetworkRef" :tree-data="graphTreeData" :noContextMenu="true"
11 @nodeItemClick="handleNodeItemClick">
12 </RelationNetwork>
13 <Sankey v-show="!isGraphDisplay && (sankeyNames?.length || sankeyDataLoading)" v-loading="sankeyDataLoading"
14 :tree-data="sankeyData" :names="sankeyNames">
15 </Sankey>
16 <div v-show="(isGraphDisplay ? !graphTreeData?.guid : (!sankeyDataLoading && !sankeyNames?.length))"
17 class="main-placeholder">
18 <img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" />
19 <div class="empty-text">暂无数据</div>
20 </div>
21 </div>
22 </template>
23
24 <script lang="ts" setup name="metadataStandardQueryView">
25 import {
26 getMetaStandardField,
27 getSankeyData,
28 getMetaStandardTreeList
29 } from '@/api/modules/dataMetaService';
30 import Sankey from './components/Sankey.vue';
31 import { ElMessage } from 'element-plus';
32
33 const router = useRouter();
34 const route = useRoute()
35
36 const metaGuid = ref(route.query.guid);
37
38 const { proxy } = getCurrentInstance() as any;
39
40 const relationNetworkRef = ref();
41
42 const graphDataLoading = ref(false);
43
44 /** 关系网树形数据 */
45 const graphTreeData: any = ref({});
46
47 onBeforeUnmount(() => {
48 relationNetworkRef.value.destroy();
49 })
50
51 const sankeyDataLoading = ref(false);
52
53 const sankeyData: any = ref([]);
54
55 const sankeyNames: any = ref([]);
56
57 const isGraphDisplay = ref(true);
58
59 const displaySwitchChange = (val) => {
60 if (val == isGraphDisplay.value) {
61 return;
62 }
63 isGraphDisplay.value = val;
64 if (!val) {
65 getSankeyDataList();
66 }
67 }
68
69 const getSankeyDataList = () => {
70 sankeyDataLoading.value = true;
71 getSankeyData(metaGuid.value).then((res: any) => {
72 sankeyDataLoading.value = false;
73 if (res?.code == proxy.$passCode) {
74 sankeyData.value = res.data?.links || [];
75 sankeyNames.value = res.data?.data || [];
76 } else {
77 ElMessage.error(res.msg);
78 }
79 })
80 }
81
82 const handleNodeItemClick = (graph, nodeItem) => {
83 const nodeId = nodeItem.get('id');
84 const parentData = graph.findDataById(nodeId);
85 if (!parentData.children) {
86 parentData.children = [];
87 }
88 if (parentData.isHaveData == 'N') {
89 ElMessage.warning('没有可展开的下级字段');
90 return;
91 }
92 graphDataLoading.value = true;
93 getMetaStandardField(nodeId).then((res: any) => {
94 graphDataLoading.value = false;
95 if (res?.code == proxy.$passCode) {
96 const data = res.data || [];
97 parentData.children = [];
98 if (!data?.length) {
99 parentData.isHaveData = 'N';
100 ElMessage.warning('没有可展开的下级字段');
101 return;
102 }
103 data.forEach(d => {
104 parentData.children.push(d);
105 })
106 parentData.collapsed = false;
107 setTimeout(() => {
108 parentData.isLoading = false;
109 graph.setMaxZoom(1);
110 graph.changeData(graphTreeData.value);
111 graph.setMaxZoom(5);
112 }, 100);
113 } else {
114 parentData.isLoading = false;
115 ElMessage.error(res.msg);
116 }
117 })
118 }
119
120 onBeforeMount(() => {
121 graphDataLoading.value = true
122 getMetaStandardTreeList(metaGuid.value).then((res: any) => {
123 graphDataLoading.value = false;
124 if (res?.code == proxy.$passCode) {
125 const data = res.data || [];
126 graphTreeData.value = data?.[0] || {};
127 } else {
128 ElMessage.error(res.msg);
129 }
130 })
131 })
132
133 </script>
134
135 <style lang="scss" scoped>
136 .main_wrap {
137 height: 100%;
138 width: 100%;
139 position: relative;
140
141 :deep(.canvas-wrapper) {
142 background-color: #f7f7f9;
143 }
144
145 .main-placeholder {
146 height: 100%;
147 display: flex;
148 justify-content: center;
149 align-items: center;
150 flex-direction: column;
151
152 .empty-text {
153 font-size: 14px;
154 color: #b2b2b2;
155 }
156 }
157 }
158
159 .g6-component-topbar {
160 position: absolute;
161 left: 24px;
162 bottom: unset;
163 top: 14px;
164 padding: 0;
165 text-align: center;
166 z-index: 999;
167 }
168 </style>
...\ No newline at end of file ...\ No newline at end of file
...@@ -9,16 +9,17 @@ import Sankey from './components/Sankey.vue'; ...@@ -9,16 +9,17 @@ import Sankey from './components/Sankey.vue';
9 import Tree from '@/components/Tree/index.vue'; 9 import Tree from '@/components/Tree/index.vue';
10 import RelationNetwork from '@/components/RelationNetwork/index.vue'; 10 import RelationNetwork from '@/components/RelationNetwork/index.vue';
11 import { 11 import {
12 getMetaStandardTreeList,
13 getMetaStandardField,
14 getSankeyData
12 } from '@/api/modules/dataMetaService'; 15 } from '@/api/modules/dataMetaService';
13
14 import { useRouter, useRoute } from "vue-router"; 16 import { useRouter, useRoute } from "vue-router";
15 import useDataMetaStore from "@/store/modules/dataMeta" 17 import useDataMetaStore from "@/store/modules/dataMeta"
18 import { cloneDeep } from 'lodash-es';
16 19
17 const router = useRouter(); 20 const router = useRouter();
18 const route = useRoute() 21 const route = useRoute()
19 22
20 const switchGraphDisplay = ref(true); //true表示关系网,false表示桑基图
21
22 const { proxy } = getCurrentInstance() as any; 23 const { proxy } = getCurrentInstance() as any;
23 24
24 const relationNetworkRef = ref(); 25 const relationNetworkRef = ref();
...@@ -27,14 +28,14 @@ const treeInfo = ref({ ...@@ -27,14 +28,14 @@ const treeInfo = ref({
27 id: "data-meta-standard-tree", 28 id: "data-meta-standard-tree",
28 filter: true, 29 filter: true,
29 queryValue: "", 30 queryValue: "",
30 queryPlaceholder: "输入库/表名称搜索", 31 queryPlaceholder: "请输入关键字搜索",
31 props: { 32 props: {
32 label: "name", 33 label: "standardName",
33 value: "guid", 34 value: "guid",
34 isLeaf: "isLeaf", 35 isLeaf: "isLeaf",
35 }, 36 },
36 nodeKey: 'guid', 37 nodeKey: 'guid',
37 expandedKey: ['1'], 38 expandedKey: [],
38 currentNodeKey: '', 39 currentNodeKey: '',
39 expandOnNodeClick: false, 40 expandOnNodeClick: false,
40 data: <any>[], 41 data: <any>[],
...@@ -44,51 +45,20 @@ const treeInfo = ref({ ...@@ -44,51 +45,20 @@ const treeInfo = ref({
44 /** 获取左侧树数据. */ 45 /** 获取左侧树数据. */
45 const getTreeData = async () => { 46 const getTreeData = async () => {
46 treeInfo.value.loading = true 47 treeInfo.value.loading = true
47 // let params = {} 48 getMetaStandardTreeList('').then((res: any) => {
48 // const res: any = await getMetaTreeData(params) 49 treeInfo.value.loading = false;
49 // if (res.code == proxy.$passCode) { 50 if (res?.code == proxy.$passCode) {
50 // const data = res.data || []; 51 const data = res.data || [];
51 // let treeData: any = Object.keys(data).length ? [data] : []; 52 treeInfo.value.data = data;
52 // treeInfo.value.data = treeData; 53 if (data.length) {
53 // allTreeData.value = treeData; 54 treeInfo.value.currentNodeKey = data[0].guid;
54 // if (treeData.length) { 55 treeInfo.value.expandedKey = <any>[data[0].guid];
55 // treeInfo.value.currentNodeKey = treeData[0].guid; 56 nodeClick(treeInfo.value.data[0])
56 // treeInfo.value.expandedKey = <any>[treeData[0].guid]; 57 }
57 // } 58 } else {
58 // } else { 59 ElMessage.error(res.msg);
59 // ElMessage.error(res.msg); 60 }
60 // } 61 })
61 treeInfo.value.data = [{
62 guid: '1',
63 name: '第一级1',
64 children: [{
65 guid: '1-1',
66 name: '第二级1-1',
67 children: [{
68 guid: '1-1-1',
69 name: '第三级1-1-1'
70 }]
71 }, {
72 guid: '1-2',
73 name: '第二级1-2'
74 }, {
75 guid: '1-3',
76 name: '第二级1-3'
77 }]
78 }, {
79 guid: '2',
80 name: '第一级2',
81 children: [{
82 guid: '2-1',
83 name: '第二级1-1'
84 }, {
85 guid: '2-2',
86 name: '第二级1-2'
87 }]
88 }];
89 treeInfo.value.loading = false
90 treeInfo.value.currentNodeKey = '1';
91 nodeClick(treeInfo.value.data[0])
92 } 62 }
93 /** 左侧树的的组件引用. */ 63 /** 左侧树的的组件引用. */
94 const treeInfoRef = ref(); 64 const treeInfoRef = ref();
...@@ -98,22 +68,18 @@ const lastClickNode: any = ref({}); ...@@ -98,22 +68,18 @@ const lastClickNode: any = ref({});
98 68
99 const treeDataLoading = ref(false); 69 const treeDataLoading = ref(false);
100 70
101 /** 数据血缘关系图组件 */
102 const lineageGraph: any = ref();
103
104 /** 点击左侧树节点,更新对应的血缘关系图. */ 71 /** 点击左侧树节点,更新对应的血缘关系图. */
105 const nodeClick = (data) => { 72 const nodeClick = (data) => {
106 console.log(data);
107 const ele = <HTMLElement>document.querySelector(".g6-component-contextmenu") 73 const ele = <HTMLElement>document.querySelector(".g6-component-contextmenu")
108 if (ele) { 74 if (ele) {
109 ele.style.display = "none" 75 ele.style.display = "none"
110 } 76 }
111 nextTick(() => {
112 lineageGraph.value?.tooltip1.hide()
113 })
114 treeInfo.value.currentNodeKey = data.guid; 77 treeInfo.value.currentNodeKey = data.guid;
115 treeInfo.value.expandedKey = <any>[data.guid]; 78 treeInfo.value.expandedKey = <any>[data.guid];
116 lastClickNode.value = data; 79 lastClickNode.value = cloneDeep(data);
80 if (!isGraphDisplay.value) {
81 getSankeyDataList();
82 }
117 } 83 }
118 84
119 /** 选中树节点后自动滚动到可视范围内. */ 85 /** 选中树节点后自动滚动到可视范围内. */
...@@ -145,7 +111,6 @@ const processRouter = () => { ...@@ -145,7 +111,6 @@ const processRouter = () => {
145 treeInfo.value.expandedKey = <any>[databaseGuid, guid]; 111 treeInfo.value.expandedKey = <any>[databaseGuid, guid];
146 lastClickNode.value = { guid: guid, tableName, databaseName, type: 3, databaseChName }; 112 lastClickNode.value = { guid: guid, tableName, databaseName, type: 3, databaseChName };
147 scrollToNode(guid); 113 scrollToNode(guid);
148 switchGraphDisplay.value = isFL;
149 // if (isFL) { 114 // if (isFL) {
150 // getAllTableFieldLineageMap(); 115 // getAllTableFieldLineageMap();
151 // } else { 116 // } else {
...@@ -156,20 +121,45 @@ const processRouter = () => { ...@@ -156,20 +121,45 @@ const processRouter = () => {
156 } 121 }
157 122
158 onActivated(() => { 123 onActivated(() => {
159 processRouter(); 124 //processRouter();
160 }); 125 });
161 126
162 onBeforeMount(async () => { 127 onBeforeMount(async () => {
163 await getTreeData() 128 await getTreeData()
164 processRouter(); 129 // processRouter();
165 }) 130 })
166 131
167 onMounted(() => { }) 132 onMounted(() => { })
168 133
134 const sankeyDataLoading = ref(false);
135
136 const sankeyData: any = ref([]);
137
138 const sankeyNames: any = ref([]);
139
169 const isGraphDisplay = ref(true); 140 const isGraphDisplay = ref(true);
170 141
171 const displaySwitchChange = (val) => { 142 const displaySwitchChange = (val) => {
143 if (val == isGraphDisplay.value) {
144 return;
145 }
172 isGraphDisplay.value = val; 146 isGraphDisplay.value = val;
147 if (!val) {
148 getSankeyDataList();
149 }
150 }
151
152 const getSankeyDataList = () => {
153 sankeyDataLoading.value = true;
154 getSankeyData(lastClickNode.value.guid).then((res: any) => {
155 sankeyDataLoading.value = false;
156 if (res?.code == proxy.$passCode) {
157 sankeyData.value = res.data?.links || [];
158 sankeyNames.value = res.data?.data || [];
159 } else {
160 ElMessage.error(res.msg);
161 }
162 })
173 } 163 }
174 164
175 const handleNodeItemClick = (graph, nodeItem) => { 165 const handleNodeItemClick = (graph, nodeItem) => {
...@@ -178,35 +168,41 @@ const handleNodeItemClick = (graph, nodeItem) => { ...@@ -178,35 +168,41 @@ const handleNodeItemClick = (graph, nodeItem) => {
178 if (!parentData.children) { 168 if (!parentData.children) {
179 parentData.children = []; 169 parentData.children = [];
180 } 170 }
171 if (parentData.noData) {
172 ElMessage.warning('没有可展开的下级字段');
173 return;
174 }
181 treeDataLoading.value = true; 175 treeDataLoading.value = true;
182 let childData = [{ 176 getMetaStandardField(nodeId).then((res: any) => {
183 guid: '33',
184 isField: true,
185 name: '字段1'
186 }, {
187 guid: '44',
188 isField: true,
189 name: '字段2字段2字段2字段2字段2字段2字段2字段2字段2xx2字段22字段22字段22字段22字段22字段2'
190 }, {
191 guid: '55',
192 isField: true,
193 name: '字段3'
194 }]
195 // parentData.collapsed = true;
196 // nodeItem.getModel().collapsed = true;
197 parentData.children = childData;
198 setTimeout(() => {
199 treeDataLoading.value = false; 177 treeDataLoading.value = false;
200 graph.changeData(); 178 if (res?.code == proxy.$passCode) {
201 // parentData.collapsed = true; 179 const data = res.data || [];
202 // graph.updateChildren(childData, parentData.id); 180 parentData.children = [];
203 // graph.changeData(lastClickNode.value); 181 if (!data?.length) {
204 //graph.data(lastClickNode.value); 182 parentData.noData = true;
205 }, 2000) 183 ElMessage.warning('没有可展开的下级字段');
184 return;
185 }
186 data.forEach(d => {
187 parentData.children.push(d);
188 })
189 parentData.collapsed = false;
190 setTimeout(() => {
191 parentData.isLoading = false;
192 graph.setMaxZoom(1);
193 graph.changeData(lastClickNode.value);
194 graph.setMaxZoom(5);
195 }, 100);
196 } else {
197 parentData.isLoading = false;
198 ElMessage.error(res.msg);
199 }
200 })
206 } 201 }
207 202
208 const handleContextMenu = (nodeData) => { 203 const handleContextMenu = (nodeData) => {
209 //TODO,新建引用数据集 204 //TODO,新建引用数据集
205 window.open('');
210 } 206 }
211 207
212 onBeforeUnmount(() => { 208 onBeforeUnmount(() => {
...@@ -218,21 +214,23 @@ onBeforeUnmount(() => { ...@@ -218,21 +214,23 @@ onBeforeUnmount(() => {
218 <template> 214 <template>
219 <div class="container_wrap full flex"> 215 <div class="container_wrap full flex">
220 <div class="aside_wrap"> 216 <div class="aside_wrap">
221 <div class="aside_title">数据库目录列表</div> 217 <div class="aside_title">元数据标准列表</div>
222 <Tree ref="treeInfoRef" :treeInfo="treeInfo" @nodeClick="nodeClick" /> 218 <Tree ref="treeInfoRef" :treeInfo="treeInfo" @nodeClick="nodeClick" />
223 </div> 219 </div>
224 <div class="main_wrap"> 220 <div class="main_wrap">
225 <div className='g6-component-topbar'> 221 <div className='g6-component-topbar'>
226 <graphTopbar ref="topBarRef" @displaySwitchChange="displaySwitchChange" :isGraphDisplay="isGraphDisplay" /> 222 <graphTopbar ref="topBarRef" @displaySwitchChange="displaySwitchChange" :isGraphDisplay="isGraphDisplay" />
227 </div> 223 </div>
228 <RelationNetwork v-show="isGraphDisplay" ref="relationNetworkRef" :tree-data="lastClickNode" 224 <RelationNetwork v-show="lastClickNode?.guid && isGraphDisplay" ref="relationNetworkRef"
229 v-loading="treeDataLoading" @nodeItemClick="handleNodeItemClick" @contextMenu="handleContextMenu"> 225 :tree-data="lastClickNode" v-loading="treeDataLoading" @nodeItemClick="handleNodeItemClick"
226 @contextMenu="handleContextMenu">
230 </RelationNetwork> 227 </RelationNetwork>
231 <Sankey v-show="!isGraphDisplay"></Sankey> 228 <Sankey v-show="lastClickNode?.guid && !isGraphDisplay && (sankeyNames?.length || sankeyDataLoading)" v-loading="sankeyDataLoading" :tree-data="sankeyData" :names="sankeyNames">
232 <!-- <div v-show="lastClickNode && lastClickNode?.type !== 3 && lastClickNode?.type !== 4" class="main-placeholder"> 229 </Sankey>
230 <div v-show="!lastClickNode?.guid && !treeInfo.data?.length || (!isGraphDisplay && !sankeyDataLoading && !sankeyNames?.length)" class="main-placeholder">
233 <img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" /> 231 <img src="../../assets/images/no-data.png" :style="{ width: '96px', height: '96px' }" />
234 <div class="empty-text">暂无标准数据</div> 232 <div class="empty-text">暂无数据</div>
235 </div> --> 233 </div>
236 </div> 234 </div>
237 </div> 235 </div>
238 </template> 236 </template>
......
...@@ -416,6 +416,17 @@ function exportData () { ...@@ -416,6 +416,17 @@ function exportData () {
416 onBeforeMount(() => { 416 onBeforeMount(() => {
417 getTree() 417 getTree()
418 }) 418 })
419
420 const viewGraph = () => {
421 router.push({
422 name: 'metadataStandardQueryView',
423 query: {
424 guid: treeInfo.value.currentObj?.guid,
425 name: treeInfo.value.currentObj?.standardName,
426 }
427 });
428 }
429
419 </script> 430 </script>
420 431
421 <template> 432 <template>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!