feat(xpack): 血缘分析

This commit is contained in:
dataeaseShu 2024-08-16 15:55:18 +08:00
parent f2ec5a2c0d
commit f07f00aa56
5 changed files with 277 additions and 26 deletions

View File

@ -120,6 +120,12 @@ export const delDatasetTree = async (id): Promise<IResponse> => {
})
}
export const perDelete = async (id): Promise<boolean> => {
return request.post({ url: `/datasetTree/perDelete/${id}`, data: {} }).then(res => {
return res?.data
})
}
export const getDatasourceList = async (): Promise<IResponse> => {
return request.post({ url: '/datasource/tree', data: { busiFlag: 'datasource' } }).then(res => {
return res?.data

View File

@ -91,6 +91,12 @@ export const save = async (data = {}): Promise<Dataset> => {
})
}
export const perDeleteDatasource = async (id): Promise<boolean> => {
return request.post({ url: `/datasource//perDelete/${id}`, data: {} }).then(res => {
return res?.data
})
}
export const update = async (data = {}): Promise<Dataset> => {
return request.post({ url: '/datasource/update', data }).then(res => {
return res?.data

View File

@ -0,0 +1,127 @@
<script lang="ts" setup>
import { ref, reactive, nextTick } from 'vue'
import { XpackComponent } from '@/components/plugin'
import { cloneDeep } from 'lodash-es'
import {
getDatasourceRelationship as getDatasourceRelation,
getDatasetRelationship as getDatasetRelation
} from '@/api/relation/index'
const relationDrawer = ref(false)
const chartSize = reactive({
height: 0,
width: 0
})
const getChartSize = () => {
const dom = document.querySelector('.relation-drawer_content')
if (!dom) return
Object.assign(chartSize, {
height: dom.offsetHeight + 'px',
width: dom.offsetWidth + 'px'
})
}
const consanguinity = ref()
let resRef = null
const getDatasourceRelationship = id => {
getDatasourceRelation(id)
.then(res => {
resRef = cloneDeep(res || {})
})
.finally(() => {
tableLoading.value = false
nextTick(() => {
consanguinity.value.invokeMethod({
methodName: 'getChartData',
args: {
info: current,
res: resRef
}
})
})
})
}
const getDatasetRelationship = id => {
getDatasetRelation(id)
.then(res => {
resRef = cloneDeep(res || {})
})
.finally(() => {
tableLoading.value = false
nextTick(() => {
consanguinity.value.invokeMethod({
methodName: 'getChartData',
args: {
info: current,
res: resRef
}
})
})
})
}
const current = {
queryType: '',
num: '',
label: ''
}
const tableLoading = ref(false)
const getChartData = obj => {
Object.assign(current, obj || {})
const { queryType, num } = current
tableLoading.value = true
relationDrawer.value = true
nextTick(() => {
getChartSize()
switch (queryType) {
case 'datasource':
getDatasourceRelationship(num)
break
case 'dataset':
getDatasetRelationship(num)
break
default:
break
}
})
}
defineExpose({
getChartData
})
</script>
<template>
<el-drawer
title="血缘关系图"
v-model="relationDrawer"
custom-class="de-relation-drawer"
size="1200px"
direction="rtl"
>
<div v-loading="tableLoading" class="relation-drawer_content">
<XpackComponent
ref="consanguinity"
:chart-size="chartSize"
:current="current"
detailDisabled
jsname="L21lbnUvc3lzdGVtL2Fzc29jaWF0aW9uL0NoYXJ0"
/>
</div>
</el-drawer>
</template>
<style lang="less">
.de-relation-drawer {
.ed-drawer__body {
padding-bottom: 24px;
}
.relation-drawer_content {
border: 1px solid #dee0e3;
width: 100%;
height: 100%;
background: #f5f6f7;
border-radius: 4px;
position: relative;
}
}
</style>

View File

@ -1,11 +1,13 @@
<script lang="tsx" setup>
import { useI18n } from '@/hooks/web/useI18n'
import { ref, reactive, shallowRef, computed, watch, onBeforeMount, nextTick, unref } from 'vue'
import { ref, reactive, shallowRef, computed, watch, onBeforeMount, nextTick, unref, h } from 'vue'
import ArrowSide from '@/views/common/DeResourceArrow.vue'
import { useEmbedded } from '@/store/modules/embedded'
import { useEmitt } from '@/hooks/web/useEmitt'
import relationChart from '@/components/relation-chart/index.vue'
import {
ElIcon,
ElButton,
ElMessageBox,
ElMessage,
type ElMessageBoxOptions,
@ -18,7 +20,7 @@ import { useMoveLine } from '@/hooks/web/useMoveLine'
import { useRouter, useRoute } from 'vue-router'
import CreatDsGroup from './form/CreatDsGroup.vue'
import type { BusiTreeNode, BusiTreeRequest } from '@/models/tree/TreeNode'
import { delDatasetTree, getDatasetPreview, barInfoApi } from '@/api/dataset'
import { delDatasetTree, getDatasetPreview, barInfoApi, perDelete } from '@/api/dataset'
import EmptyBackground from '@/components/empty-background/src/EmptyBackground.vue'
import DeResourceGroupOpt from '@/views/common/DeResourceGroupOpt.vue'
import DatasetDetail from './DatasetDetail.vue'
@ -352,7 +354,7 @@ const handleClick = (tabName: TabPaneName) => {
break
}
}
const relationChartRef = ref()
const operation = (cmd: string, data: BusiTreeNode, nodeType: string) => {
if (cmd === 'copy') {
if (isDataEaseBi.value) {
@ -384,17 +386,65 @@ const operation = (cmd: string, data: BusiTreeNode, nodeType: string) => {
delete options.tip
}
ElMessageBox.confirm(
nodeType === 'folder'
? t('data_set.delete_this_folder')
: t('datasource.delete_this_dataset'),
options as ElMessageBoxOptions
).then(() => {
delDatasetTree(data.id).then(() => {
getData()
ElMessage.success(t('dataset.delete_success'))
if (nodeType !== 'folder') {
perDelete(data.id).then(res => {
if (res === true) {
const onClick = () => {
relationChartRef.value.getChartData({
queryType: 'dataset',
num: data.id,
label: data.name
})
}
ElMessageBox.confirm('', {
confirmButtonType: 'danger',
type: 'warning',
autofocus: false,
confirmButtonText: '确定',
showClose: false,
dangerouslyUseHTMLString: true,
message: h('div', null, [
h('p', { style: 'margin-bottom: 8px;' }, '确定删除该数据集吗?'),
h(
'p',
{ class: 'tip' },
'该数据集存在如下血缘关系,删除会造成相关仪表板的视图失效,确定删除?'
),
h(
ElButton,
{ text: true, onClick: onClick, style: 'margin-left: -4px;' },
'查看血缘关系'
)
])
}).then(() => {
delDatasetTree(data.id).then(() => {
getData()
ElMessage.success(t('dataset.delete_success'))
})
})
} else {
ElMessageBox.confirm(
t('datasource.delete_this_dataset'),
options as ElMessageBoxOptions
).then(() => {
delDatasetTree(data.id).then(() => {
getData()
ElMessage.success(t('dataset.delete_success'))
})
})
}
})
})
} else {
ElMessageBox.confirm(t('data_set.delete_this_folder'), options as ElMessageBoxOptions).then(
() => {
delDatasetTree(data.id).then(() => {
getData()
ElMessage.success(t('dataset.delete_success'))
})
}
)
}
} else {
creatDsFolder.value.createInit(nodeType, data, cmd)
}
@ -846,6 +896,7 @@ const getMenuList = (val: boolean) => {
<empty-background :description="t('deDataset.on_the_left')" img-type="select" />
</template>
</div>
<relationChart ref="relationChartRef"></relationChart>
<de-resource-group-opt
:cur-canvas-type="curCanvasType"
@finish="resourceOptFinish"

View File

@ -1,15 +1,23 @@
<script lang="tsx" setup>
import { computed, unref, reactive, ref, shallowRef, nextTick, watch, onMounted } from 'vue'
import { computed, h, unref, reactive, ref, shallowRef, nextTick, watch, onMounted } from 'vue'
import { dsTypes } from '@/views/visualized/data/datasource/form/option'
import type { TabPaneName, ElMessageBoxOptions } from 'element-plus-secondary'
import { ElIcon, ElMessageBox, ElMessage, ElScrollbar, ElAside } from 'element-plus-secondary'
import {
ElIcon,
ElButton,
ElMessageBox,
ElMessage,
ElScrollbar,
ElAside
} from 'element-plus-secondary'
import GridTable from '@/components/grid-table/src/GridTable.vue'
import ArrowSide from '@/views/common/DeResourceArrow.vue'
import relationChart from '@/components/relation-chart/index.vue'
import { HandleMore } from '@/components/handle-more'
import { Icon } from '@/components/icon-custom'
import { fieldType } from '@/utils/attr'
import { useEmitt } from '@/hooks/web/useEmitt'
import { getHidePwById, listSyncRecord, uploadFile } from '@/api/datasource'
import { getHidePwById, listSyncRecord, uploadFile, perDeleteDatasource } from '@/api/datasource'
import CreatDsGroup from './form/CreatDsGroup.vue'
import type { Tree } from '../dataset/form/CreatDsGroup.vue'
import { previewData, getById } from '@/api/datasource'
@ -738,6 +746,7 @@ const handleDatasourceTree = (cmd: string, data?: Tree) => {
creatDsFolder.value.createInit(cmd, data || {})
}
}
const relationChartRef = ref()
const operation = (cmd: string, data: Tree, nodeType: string) => {
if (cmd === 'copy') {
handleCopy(data)
@ -758,18 +767,69 @@ const operation = (cmd: string, data: Tree, nodeType: string) => {
} else {
delete options.tip
}
ElMessageBox.confirm(
nodeType === 'folder' ? '确定删除该文件夹吗' : t('datasource.this_data_source'),
options as ElMessageBoxOptions
).then(() => {
deleteById(data.id as number).then(() => {
if (data.id === nodeInfo.id) {
Object.assign(nodeInfo, cloneDeep(defaultInfo))
if (nodeType !== 'folder') {
perDeleteDatasource(data.id).then(res => {
if (res === true) {
const onClick = () => {
relationChartRef.value.getChartData({
queryType: 'datasource',
num: data.id,
label: data.name
})
}
ElMessageBox.confirm('', {
confirmButtonType: 'danger',
type: 'warning',
autofocus: false,
confirmButtonText: '确定',
showClose: false,
dangerouslyUseHTMLString: true,
message: h('div', null, [
h('p', { style: 'margin-bottom: 8px;' }, '确定删除该数据源吗?'),
h('p', { class: 'tip' }, '有数据集正在使用此数据源,删除后数据集不可用,确认删除?'),
h(
ElButton,
{ text: true, onClick: onClick, style: 'margin-left: -4px;' },
'查看血缘关系'
)
])
}).then(() => {
deleteById(data.id as number).then(() => {
if (data.id === nodeInfo.id) {
Object.assign(nodeInfo, cloneDeep(defaultInfo))
}
listDs()
ElMessage.success(t('dataset.delete_success'))
})
})
} else {
ElMessageBox.confirm(
t('datasource.this_data_source'),
options as ElMessageBoxOptions
).then(() => {
deleteById(data.id as number).then(() => {
if (data.id === nodeInfo.id) {
Object.assign(nodeInfo, cloneDeep(defaultInfo))
}
listDs()
ElMessage.success(t('dataset.delete_success'))
})
})
}
listDs()
ElMessage.success(t('dataset.delete_success'))
})
})
} else {
ElMessageBox.confirm('确定删除该文件夹吗', options as ElMessageBoxOptions).then(() => {
deleteById(data.id as number).then(() => {
if (data.id === nodeInfo.id) {
Object.assign(nodeInfo, cloneDeep(defaultInfo))
}
listDs()
ElMessage.success(t('dataset.delete_success'))
})
})
}
} else {
creatDsFolder.value.createInit(nodeType, data, cmd)
}
@ -1661,6 +1721,7 @@ const getMenuList = (val: boolean) => {
</span>
</template>
</el-dialog>
<relationChart ref="relationChartRef"></relationChart>
<XpackComponent
jsname="L2NvbXBvbmVudC9wbHVnaW5zLWhhbmRsZXIvRHNDYXRlZ29yeUhhbmRsZXI="