You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.0 KiB
145 lines
4.0 KiB
1 month ago
|
<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,
|
||
|
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.name}</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)
|
||
|
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 > 2) {
|
||
|
const customNode = node.children[node.children.length - 1] as any
|
||
|
customNode.name = `${node.children[0].name} ~ ${node.children[node.children.length - 2].name}`
|
||
|
customNode.customNode = true
|
||
|
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>
|