|
|
|
<template>
|
|
|
|
<div class="relative h-full w-full">
|
|
|
|
<el-button type="primary" @click="onBack" class="absolute top-0 z-99">
|
|
|
|
<i class="i-line-md:arrow-left"></i>返回站点数据
|
|
|
|
</el-button>
|
|
|
|
<el-empty v-if="!topologyTree && !loading" class="w-full h-full"></el-empty>
|
|
|
|
<div
|
|
|
|
id="container"
|
|
|
|
class="w-full h-full"
|
|
|
|
v-loading="loading"
|
|
|
|
element-loading-text="设备加载中请稍等..."
|
|
|
|
style="width: 100%;height: 100%">
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<detail-drawer ref="detailDrawerRef"/>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
import { NODE_SIZE } from "./utils";
|
|
|
|
import { useG6 } from "@/hooks/useG6";
|
|
|
|
import Node from './components/Node.vue'
|
|
|
|
import { flattenTree } from "@/views/testG6/utils";
|
|
|
|
import { type PluginOptions } from "@antv/g6"
|
|
|
|
import type { IDevice, IOfflineDevice, IOnlineDevice } from "@/views/stationData/type";
|
|
|
|
import { getPointGroup, type IPointGroupParams, type IPointGroupOV } from "@/api/module/transfer";
|
|
|
|
import DetailDrawer from "./components/detailDrawer.vue";
|
|
|
|
|
|
|
|
const router = useRouter()
|
|
|
|
|
|
|
|
const route = useRoute()
|
|
|
|
const deviceInfo = route.query?.deviceInfo
|
|
|
|
? JSON.parse(route.query?.deviceInfo as string)
|
|
|
|
: {} as unknown as IDevice & { isonLine: boolean, siteName: string }
|
|
|
|
|
|
|
|
const detailDrawerRef = ref<InstanceType<typeof DetailDrawer>>()
|
|
|
|
const topologyTree = ref<IPointGroupOV>()
|
|
|
|
const loading = ref(true)
|
|
|
|
|
|
|
|
async function loadDeviceTopology() {
|
|
|
|
const params: IPointGroupParams = {}
|
|
|
|
if (deviceInfo.isonLine) {
|
|
|
|
const onlineDevice = deviceInfo as IOnlineDevice
|
|
|
|
params.isLocal = false
|
|
|
|
params.host = onlineDevice.clientIp
|
|
|
|
} else {
|
|
|
|
const offlineDevice = deviceInfo as unknown as IOfflineDevice & { siteName: string }
|
|
|
|
params.sn = offlineDevice.sn
|
|
|
|
params.site = offlineDevice!.siteName
|
|
|
|
params.isLocal = true
|
|
|
|
}
|
|
|
|
|
|
|
|
const res = await getPointGroup(params)
|
|
|
|
if (res.code === 0) {
|
|
|
|
topologyTree.value = {
|
|
|
|
id: deviceInfo.sn,
|
|
|
|
ip: deviceInfo.ip,
|
|
|
|
name: deviceInfo?.sn,
|
|
|
|
cnName: deviceInfo?.name ?? deviceInfo?.sn,
|
|
|
|
port: deviceInfo.port,
|
|
|
|
slave_addr: 'root',
|
|
|
|
type: deviceInfo?.type ?? 'emu',
|
|
|
|
children: []
|
|
|
|
}
|
|
|
|
topologyTree.value.children = Array.isArray(res?.data) ? res.data : []
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const canvas = ref<HTMLElement | undefined>(undefined)
|
|
|
|
|
|
|
|
const plugins: PluginOptions = [
|
|
|
|
{
|
|
|
|
type: 'contextmenu',
|
|
|
|
enable: (e: any) => e.targetType === 'node',
|
|
|
|
getItems: () => {
|
|
|
|
return [{ name: '查看详情', value: 'detail' }];
|
|
|
|
},
|
|
|
|
onClick: onDetail,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
type: 'tooltip',
|
|
|
|
enable: (e: any) => e.targetType === 'node',
|
|
|
|
getContent: (e: any, items: any) => {
|
|
|
|
console.log(items)
|
|
|
|
return `<div>${items[0].data.cnName}</div>`;
|
|
|
|
},
|
|
|
|
},
|
|
|
|
]
|
|
|
|
|
|
|
|
function init() {
|
|
|
|
if (!topologyTree.value) return
|
|
|
|
const filteredTree = filterTree(topologyTree.value)
|
|
|
|
const device = flattenTree([filteredTree])
|
|
|
|
|
|
|
|
const { container, graph } = useG6({
|
|
|
|
tree: device,
|
|
|
|
nodeComponent: Node,
|
|
|
|
nodeSize: NODE_SIZE
|
|
|
|
}, plugins)
|
|
|
|
canvas.value = container.value
|
|
|
|
graph.render();
|
|
|
|
}
|
|
|
|
|
|
|
|
function onDetail(value: string, item: HTMLElement, current: any) {
|
|
|
|
const nodeData = current.config.context.model.getNodeData(current.config.id)
|
|
|
|
console.log(nodeData[nodeData.length - 1].data)
|
|
|
|
const device = deviceInfo as unknown as IDevice & {
|
|
|
|
isonLine: boolean
|
|
|
|
siteName: string
|
|
|
|
}
|
|
|
|
detailDrawerRef.value?.open(device, nodeData[nodeData.length - 1].data)
|
|
|
|
}
|
|
|
|
|
|
|
|
onMounted(async () => {
|
|
|
|
await loadDeviceTopology()
|
|
|
|
loading.value = false
|
|
|
|
init()
|
|
|
|
})
|
|
|
|
|
|
|
|
function filterTree(node: IPointGroupOV) {
|
|
|
|
if (node.type === 'bms_cluster' && Array.isArray(node.children)) {
|
|
|
|
if (node.children.length > 1) {
|
|
|
|
const customNode = node.children[0] as any
|
|
|
|
node.children.forEach(r => {
|
|
|
|
r.customCnName = r.cnName
|
|
|
|
})
|
|
|
|
customNode.cnName = `${node.children[0].cnName} ~ ${node.children[node.children.length - 1].cnName}`
|
|
|
|
customNode.customNode = true
|
|
|
|
customNode.brother = node.children
|
|
|
|
node.children = [customNode]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Array.isArray(node.children)) {
|
|
|
|
node!.children = node.children.map((child: any) => {
|
|
|
|
child.parentName = node.name
|
|
|
|
return filterTree(child)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
return node
|
|
|
|
}
|
|
|
|
|
|
|
|
function onBack() {
|
|
|
|
router.push('/station')
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
|
|
|
|
|
</style>
|