fix: 简化设备树选中状态与路由同步的逻辑,修复选中的设备类型被异常还原的问题
This commit is contained in:
@@ -4,7 +4,7 @@ import { useDeviceTree, usePermission, type UseDeviceTreeReturn } from '@/compos
|
|||||||
import { DEVICE_TYPE_NAMES, DEVICE_TYPE_LITERALS, tryGetDeviceType, type DeviceType, PERMISSION_TYPE_LITERALS } from '@/enums';
|
import { DEVICE_TYPE_NAMES, DEVICE_TYPE_LITERALS, tryGetDeviceType, type DeviceType, PERMISSION_TYPE_LITERALS } from '@/enums';
|
||||||
import { isNvrCluster } from '@/helpers';
|
import { isNvrCluster } from '@/helpers';
|
||||||
import { useDeviceStore, usePermissionStore } from '@/stores';
|
import { useDeviceStore, usePermissionStore } from '@/stores';
|
||||||
import { watchImmediate } from '@vueuse/core';
|
import { watchDebounced, watchImmediate } from '@vueuse/core';
|
||||||
import destr from 'destr';
|
import destr from 'destr';
|
||||||
import { isFunction } from 'es-toolkit';
|
import { isFunction } from 'es-toolkit';
|
||||||
import {
|
import {
|
||||||
@@ -27,7 +27,7 @@ import {
|
|||||||
type TreeProps,
|
type TreeProps,
|
||||||
} from 'naive-ui';
|
} from 'naive-ui';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { computed, h, nextTick, onBeforeUnmount, ref, toRefs, useTemplateRef, watch, type CSSProperties } from 'vue';
|
import { computed, h, nextTick, onBeforeUnmount, onMounted, ref, toRefs, useTemplateRef, watch, type CSSProperties } from 'vue';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
/**
|
/**
|
||||||
@@ -67,15 +67,15 @@ const {
|
|||||||
selectedStationCode,
|
selectedStationCode,
|
||||||
selectedDeviceType,
|
selectedDeviceType,
|
||||||
selectedDevice,
|
selectedDevice,
|
||||||
|
syncFromRoute,
|
||||||
|
syncToRoute,
|
||||||
selectDevice,
|
selectDevice,
|
||||||
// 设备管理
|
// 设备管理
|
||||||
exportDevice,
|
exportDevice,
|
||||||
exportDeviceTemplate,
|
exportDeviceTemplate,
|
||||||
importDevice,
|
importDevice,
|
||||||
deleteDevice,
|
deleteDevice,
|
||||||
} = useDeviceTree({
|
} = useDeviceTree();
|
||||||
syncRoute: computed(() => !!syncRoute.value),
|
|
||||||
});
|
|
||||||
|
|
||||||
// 将 `selectDevice` 函数暴露给父组件
|
// 将 `selectDevice` 函数暴露给父组件
|
||||||
emit('exposeSelectDeviceFn', selectDevice);
|
emit('exposeSelectDeviceFn', selectDevice);
|
||||||
@@ -484,11 +484,38 @@ const onLocateDeviceTree = async () => {
|
|||||||
|
|
||||||
animated.value = true;
|
animated.value = true;
|
||||||
};
|
};
|
||||||
// 渲染全线设备树时,当选择的设备发生变化,则定位设备树
|
|
||||||
|
// 当选择的设备发生变化时,定位设备树,并同步选中状态到路由参数
|
||||||
// 暂时不考虑多次执行的问题,因为当选择的设备在设备树视口内时,不会发生滚动
|
// 暂时不考虑多次执行的问题,因为当选择的设备在设备树视口内时,不会发生滚动
|
||||||
watch(selectedDevice, async () => {
|
watch(selectedDevice, async (newDevice, oldDevice) => {
|
||||||
if (!!station.value) return;
|
if (!!station.value) return;
|
||||||
await onLocateDeviceTree();
|
if (newDevice?.id === oldDevice?.id) return;
|
||||||
|
// console.log('selectedDevice changed');
|
||||||
|
onLocateDeviceTree();
|
||||||
|
syncToRoute();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 当全线设备发生变化时,从路由参数同步选中状态
|
||||||
|
// 但lineDevices是shallowRef,因此需要深度侦听才能获取内部变化,
|
||||||
|
// 而单纯的深度侦听又可能会引发性能问题,因此尝试使用防抖侦听
|
||||||
|
watchDebounced(
|
||||||
|
lineDevices,
|
||||||
|
(newLineDevices) => {
|
||||||
|
if (syncRoute.value) {
|
||||||
|
// console.log('lineDevices changed');
|
||||||
|
syncFromRoute(newLineDevices);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
debounce: 500,
|
||||||
|
deep: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
if (syncRoute.value) {
|
||||||
|
syncFromRoute(lineDevices.value);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,39 +1,33 @@
|
|||||||
import type { LineDevices, NdmDeviceResultVO, Station } from '@/apis';
|
import type { LineDevices, NdmDeviceResultVO, Station } from '@/apis';
|
||||||
import { tryGetDeviceType, type DeviceType } from '@/enums';
|
import { tryGetDeviceType, type DeviceType } from '@/enums';
|
||||||
import { useDeviceStore } from '@/stores';
|
import { ref } from 'vue';
|
||||||
import { watchDebounced } from '@vueuse/core';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { onMounted, ref, toValue, watch, type MaybeRefOrGetter } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
export const useDeviceSelection = (options?: { syncRoute?: MaybeRefOrGetter<boolean> }) => {
|
export const useDeviceSelection = () => {
|
||||||
const { syncRoute } = options ?? {};
|
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const deviceStore = useDeviceStore();
|
|
||||||
const { lineDevices } = storeToRefs(deviceStore);
|
|
||||||
|
|
||||||
const selectedStationCode = ref<Station['code']>();
|
const selectedStationCode = ref<Station['code']>();
|
||||||
const selectedDeviceType = ref<DeviceType>();
|
const selectedDeviceType = ref<DeviceType>();
|
||||||
const selectedDevice = ref<NdmDeviceResultVO>();
|
const selectedDevice = ref<NdmDeviceResultVO>();
|
||||||
|
|
||||||
const initFromRoute = (lineDevices: LineDevices) => {
|
// 从路由参数同步选中的车站、设备类型以及设备
|
||||||
const { stationCode, deviceType, deviceDbId } = route.query;
|
const syncFromRoute = (lineDevices: LineDevices) => {
|
||||||
if (stationCode) {
|
// console.log('sync from route');
|
||||||
selectedStationCode.value = stationCode as Station['code'];
|
const { stationCode: routeStationCode, deviceType: routeDeviceType, deviceDbId: routeDeviceDbId } = route.query;
|
||||||
|
if (routeStationCode) {
|
||||||
|
selectedStationCode.value = routeStationCode as Station['code'];
|
||||||
}
|
}
|
||||||
if (deviceType) {
|
if (routeDeviceType) {
|
||||||
selectedDeviceType.value = deviceType as DeviceType;
|
selectedDeviceType.value = routeDeviceType as DeviceType;
|
||||||
}
|
}
|
||||||
if (deviceDbId && selectedStationCode.value && selectedDeviceType.value) {
|
if (routeDeviceDbId && selectedStationCode.value && selectedDeviceType.value) {
|
||||||
const selectedDeviceDbId = deviceDbId as string;
|
const selectedDeviceDbId = routeDeviceDbId as string;
|
||||||
const stationDevices = lineDevices[selectedStationCode.value];
|
const stationDevices = lineDevices[selectedStationCode.value];
|
||||||
if (stationDevices) {
|
if (stationDevices) {
|
||||||
const devices = stationDevices[selectedDeviceType.value];
|
const classifiedDevices = stationDevices[selectedDeviceType.value];
|
||||||
if (devices) {
|
if (classifiedDevices) {
|
||||||
const device = devices.find((device) => device.id === selectedDeviceDbId);
|
const device = classifiedDevices.find((device) => device.id === selectedDeviceDbId);
|
||||||
if (device) {
|
if (device) {
|
||||||
selectedDevice.value = device;
|
selectedDevice.value = device;
|
||||||
}
|
}
|
||||||
@@ -51,7 +45,9 @@ export const useDeviceSelection = (options?: { syncRoute?: MaybeRefOrGetter<bool
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 将选中的车站、设备类型以及设备ID同步到路由参数
|
||||||
const syncToRoute = () => {
|
const syncToRoute = () => {
|
||||||
|
// console.log('sync to route');
|
||||||
const query = { ...route.query };
|
const query = { ...route.query };
|
||||||
// 当选中的设备发生变化时,删除fromPage参数
|
// 当选中的设备发生变化时,删除fromPage参数
|
||||||
if (selectedDevice.value?.id && route.query.deviceDbId !== selectedDevice.value.id) {
|
if (selectedDevice.value?.id && route.query.deviceDbId !== selectedDevice.value.id) {
|
||||||
@@ -69,39 +65,13 @@ export const useDeviceSelection = (options?: { syncRoute?: MaybeRefOrGetter<bool
|
|||||||
router.replace({ query });
|
router.replace({ query });
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(selectedDevice, () => {
|
|
||||||
if (toValue(syncRoute)) {
|
|
||||||
syncToRoute();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// lineDevices是shallowRef,因此需要深度侦听才能获取内部变化,
|
|
||||||
// 而单纯的深度侦听又可能会引发性能问题,因此尝试使用防抖侦听
|
|
||||||
watchDebounced(
|
|
||||||
lineDevices,
|
|
||||||
(newLineDevices) => {
|
|
||||||
if (toValue(syncRoute)) {
|
|
||||||
initFromRoute(newLineDevices);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
debounce: 500,
|
|
||||||
deep: true,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
if (toValue(syncRoute)) {
|
|
||||||
initFromRoute(lineDevices.value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectedStationCode,
|
selectedStationCode,
|
||||||
selectedDeviceType,
|
selectedDeviceType,
|
||||||
selectedDevice,
|
selectedDevice,
|
||||||
|
|
||||||
initFromRoute,
|
syncFromRoute,
|
||||||
|
syncToRoute,
|
||||||
selectDevice,
|
selectDevice,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
import type { MaybeRefOrGetter } from 'vue';
|
|
||||||
import { useDeviceManagement } from './use-device-management';
|
import { useDeviceManagement } from './use-device-management';
|
||||||
import { useDeviceSelection } from './use-device-selection';
|
import { useDeviceSelection } from './use-device-selection';
|
||||||
|
|
||||||
export const useDeviceTree = (options?: { syncRoute?: MaybeRefOrGetter<boolean> }) => {
|
export const useDeviceTree = () => {
|
||||||
const { syncRoute } = options ?? {};
|
const deviceSelection = useDeviceSelection();
|
||||||
|
|
||||||
const deviceSelection = useDeviceSelection({ syncRoute });
|
|
||||||
const deviceManagement = useDeviceManagement();
|
const deviceManagement = useDeviceManagement();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user