refactor: 重构NVR集群处理逻辑,优化设备树展示
抽离NVR集群相关的公共工具函数,重构isNvrCluster的实现逻辑。修复原有设备树中NVR分组的逻辑错误,原本会将所有单机NVR添加到每个集群的子节点中,现在会正确将单机NVR分配到对应集群,未归属的单机NVR作为独立节点。简化设备树组件的代码,统一使用封装后的工具方法处理集群分组。修复设备定位时的集群匹配逻辑,使用更准确的IP包含判断。初始化设备树数据的默认空值,修正类型定义错误。
This commit is contained in:
@@ -8,7 +8,7 @@ const createDeviceNodeKey = (stationCode?: Station['code'], device?: NdmDeviceRe
|
||||
import { initStationDevices, type NdmDeviceResultVO, type NdmNvrResultVO, type Station } from '@/apis';
|
||||
import { useDeviceTree, usePermission, type UseDeviceTreeReturn } from '@/composables';
|
||||
import { DEVICE_TYPE_NAMES, DEVICE_TYPE_LITERALS, tryGetDeviceType, type DeviceType, PERMISSION_TYPE_LITERALS } from '@/enums';
|
||||
import { isNvrCluster } from '@/helpers';
|
||||
import { createNvrClusterRelationship, isNvrCluster, nvrInCluster } from '@/helpers';
|
||||
import { useDeviceStore, usePermissionStore } from '@/stores';
|
||||
import { watchDebounced, watchImmediate } from '@vueuse/core';
|
||||
import destr from 'destr';
|
||||
@@ -297,8 +297,18 @@ const renderDeviceNodePrefix = (device: NdmDeviceResultVO, stationCode: Station[
|
||||
return h(NFlex, { size: 'small' }, { default: () => [renderViewDeviceButton(device, stationCode), renderDeviceStatusTag(device)] });
|
||||
};
|
||||
// 全线设备树
|
||||
const lineDeviceTreeData = computed<Record<Station['code'], TreeOption[]>>(() => {
|
||||
const treeData: Record<string, TreeOption[]> = {};
|
||||
const lineDeviceTreeData = computed<Record<DeviceType, TreeOption[]>>(() => {
|
||||
const treeData: Record<DeviceType, TreeOption[]> = {
|
||||
[DEVICE_TYPE_LITERALS.ndmCamera]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmNvr]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmSwitch]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmDecoder]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmSecurityBox]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmMediaServer]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmVideoServer]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmKeyboard]: [],
|
||||
[DEVICE_TYPE_LITERALS.ndmAlarmHost]: [],
|
||||
};
|
||||
deviceTabPanes.forEach(({ name: paneName /* , tab: paneTab */ }) => {
|
||||
treeData[paneName] = stations.value.map<TreeOption>((station) => {
|
||||
const { name: stationName, code: stationCode } = station;
|
||||
@@ -307,47 +317,55 @@ const lineDeviceTreeData = computed<Record<Station['code'], TreeOption[]>>(() =>
|
||||
const offlineDevices = devices?.filter((device) => device.deviceStatus === '20');
|
||||
// 对于录像机,需要根据clusterList字段以分号分隔设备IP,进一步形成子树结构
|
||||
if (paneName === DEVICE_TYPE_LITERALS.ndmNvr) {
|
||||
const nvrs = devices as NdmNvrResultVO[];
|
||||
const nvrClusters: NdmNvrResultVO[] = [];
|
||||
const nvrSingletons: NdmNvrResultVO[] = [];
|
||||
for (const device of nvrs) {
|
||||
if (isNvrCluster(device)) {
|
||||
nvrClusters.push(device);
|
||||
} else {
|
||||
nvrSingletons.push(device);
|
||||
}
|
||||
}
|
||||
const nvrDevices = devices as NdmNvrResultVO[];
|
||||
|
||||
const { nvrClusters, nvrTreeMap, nvrStandalones } = createNvrClusterRelationship(nvrDevices);
|
||||
|
||||
return {
|
||||
label: stationName,
|
||||
key: stationCode,
|
||||
prefix: () => renderStationNodePrefix(station),
|
||||
suffix: () => renderIcmpStatistics(onlineDevices?.length ?? 0, offlineDevices?.length ?? 0, devices?.length ?? 0),
|
||||
children: nvrClusters.map<TreeOption>((cluster) => {
|
||||
return {
|
||||
label: `${cluster.name}`,
|
||||
key: createDeviceNodeKey(stationCode, cluster),
|
||||
prefix: () => renderDeviceNodePrefix(cluster, stationCode),
|
||||
suffix: () => `${cluster.ipAddress}`,
|
||||
children: nvrSingletons.map<TreeOption>((device) => {
|
||||
return {
|
||||
label: `${device.name}`,
|
||||
key: createDeviceNodeKey(stationCode, device),
|
||||
prefix: () => renderDeviceNodePrefix(device, stationCode),
|
||||
suffix: () => `${device.ipAddress}`,
|
||||
// 当选择设备时,能获取到设备的所有信息,以及设备所属的车站
|
||||
stationCode,
|
||||
device: device,
|
||||
};
|
||||
}),
|
||||
// 当选择设备时,能获取到设备的所有信息,以及设备所属的车站
|
||||
stationCode,
|
||||
device: cluster,
|
||||
};
|
||||
}),
|
||||
children: [
|
||||
...nvrClusters.map((cluster) => {
|
||||
return {
|
||||
label: `${cluster.name}`,
|
||||
key: createDeviceNodeKey(stationCode, cluster),
|
||||
prefix: () => renderDeviceNodePrefix(cluster, stationCode),
|
||||
suffix: () => `${cluster.ipAddress}`,
|
||||
children: (nvrTreeMap.get(cluster.ipAddress ?? '') ?? []).map((clusterNode) => {
|
||||
return {
|
||||
label: `${clusterNode.name}`,
|
||||
key: createDeviceNodeKey(stationCode, clusterNode),
|
||||
prefix: () => renderDeviceNodePrefix(clusterNode, stationCode),
|
||||
suffix: () => `${clusterNode.ipAddress}`,
|
||||
// 当选择设备时,能获取到设备的所有信息,以及设备所属的车站
|
||||
stationCode,
|
||||
device: clusterNode,
|
||||
};
|
||||
}),
|
||||
// 当选择设备时,能获取到设备的所有信息,以及设备所属的车站
|
||||
stationCode,
|
||||
device: cluster,
|
||||
};
|
||||
}),
|
||||
...nvrStandalones.map((device) => {
|
||||
return {
|
||||
label: `${device.name}`,
|
||||
key: createDeviceNodeKey(stationCode, device),
|
||||
prefix: () => renderDeviceNodePrefix(device, stationCode),
|
||||
suffix: () => `${device.ipAddress}`,
|
||||
// 当选择设备时,能获取到设备的所有信息,以及设备所属的车站
|
||||
stationCode,
|
||||
device: device,
|
||||
};
|
||||
}),
|
||||
],
|
||||
stationCode,
|
||||
deviceType: activeTab.value,
|
||||
};
|
||||
}
|
||||
// 非录像机设备
|
||||
return {
|
||||
label: stationName,
|
||||
key: stationCode,
|
||||
@@ -382,37 +400,51 @@ const stationDeviceTreeData = computed<TreeOption[]>(() => {
|
||||
const onlineCount = stationDevices[deviceType].filter((device) => device.deviceStatus === '10').length;
|
||||
const offlineCount = stationDevices[deviceType].filter((device) => device.deviceStatus === '20').length;
|
||||
if (deviceType === DEVICE_TYPE_LITERALS.ndmNvr) {
|
||||
const nvrs = stationDevices[deviceType] as NdmNvrResultVO[];
|
||||
const clusters = nvrs.filter((nvr) => isNvrCluster(nvr));
|
||||
const singletons = nvrs.filter((nvr) => !isNvrCluster(nvr));
|
||||
const nvrDevices = stationDevices[deviceType] as NdmNvrResultVO[];
|
||||
|
||||
const { nvrClusters, nvrTreeMap, nvrStandalones } = createNvrClusterRelationship(nvrDevices);
|
||||
|
||||
return {
|
||||
label: `${DEVICE_TYPE_NAMES[deviceType]}`,
|
||||
key: deviceType,
|
||||
suffix: () => renderIcmpStatistics(onlineCount, offlineCount, nvrs.length),
|
||||
children: clusters.map<TreeOption>((cluster) => {
|
||||
return {
|
||||
label: `${cluster.name}`,
|
||||
key: createDeviceNodeKey(stationCode, cluster),
|
||||
prefix: () => renderDeviceNodePrefix(cluster, stationCode),
|
||||
suffix: () => `${cluster.ipAddress}`,
|
||||
children: singletons.map<TreeOption>((device) => {
|
||||
return {
|
||||
label: `${device.name}`,
|
||||
key: createDeviceNodeKey(stationCode, device),
|
||||
prefix: () => renderDeviceNodePrefix(device, stationCode),
|
||||
suffix: () => `${device.ipAddress}`,
|
||||
stationCode,
|
||||
device,
|
||||
};
|
||||
}),
|
||||
stationCode,
|
||||
device: cluster,
|
||||
};
|
||||
}),
|
||||
suffix: () => renderIcmpStatistics(onlineCount, offlineCount, nvrDevices.length),
|
||||
children: [
|
||||
...nvrClusters.map((cluster) => {
|
||||
return {
|
||||
label: `${cluster.name}`,
|
||||
key: createDeviceNodeKey(stationCode, cluster),
|
||||
prefix: () => renderDeviceNodePrefix(cluster, stationCode),
|
||||
suffix: () => `${cluster.ipAddress}`,
|
||||
children: (nvrTreeMap.get(cluster.ipAddress ?? '') ?? []).map((clusterNode) => {
|
||||
return {
|
||||
label: `${clusterNode.name}`,
|
||||
key: createDeviceNodeKey(stationCode, clusterNode),
|
||||
prefix: () => renderDeviceNodePrefix(clusterNode, stationCode),
|
||||
suffix: () => `${clusterNode.ipAddress}`,
|
||||
stationCode,
|
||||
device: clusterNode,
|
||||
};
|
||||
}),
|
||||
stationCode,
|
||||
device: cluster,
|
||||
};
|
||||
}),
|
||||
...nvrStandalones.map((device) => {
|
||||
return {
|
||||
label: `${device.name}`,
|
||||
key: createDeviceNodeKey(stationCode, device),
|
||||
prefix: () => renderDeviceNodePrefix(device, stationCode),
|
||||
suffix: () => `${device.ipAddress}`,
|
||||
stationCode,
|
||||
device,
|
||||
};
|
||||
}),
|
||||
],
|
||||
stationCode,
|
||||
deviceType,
|
||||
};
|
||||
}
|
||||
// 非录像机设备
|
||||
return {
|
||||
label: `${DEVICE_TYPE_NAMES[deviceType]}`,
|
||||
key: deviceType,
|
||||
@@ -488,9 +520,13 @@ const onLocateDeviceTree = async () => {
|
||||
if (stationDevices) {
|
||||
const selectedNvr = selectedDevice.value as NdmNvrResultVO;
|
||||
if (!isNvrCluster(selectedNvr)) {
|
||||
const nvrs = stationDevices[DEVICE_TYPE_LITERALS.ndmNvr];
|
||||
const clusters = nvrs.filter((nvr) => isNvrCluster(nvr) && nvr.clusterList?.includes(selectedNvr.clusterList ?? ''));
|
||||
expandedKeys.value.push(...clusters.map((nvr) => createDeviceNodeKey(stationCode, nvr)));
|
||||
const nvrDevices = stationDevices[DEVICE_TYPE_LITERALS.ndmNvr];
|
||||
const clusters = nvrDevices.filter((device) => {
|
||||
if (!isNvrCluster(device)) return false;
|
||||
const cluster = device;
|
||||
return nvrInCluster(selectedNvr, cluster);
|
||||
});
|
||||
expandedKeys.value.push(...clusters.map((cluster) => createDeviceNodeKey(stationCode, cluster)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user