fix: DevicePage fix
- remove dblclick of device node - auto scroll to selected device node
This commit is contained in:
@@ -24,9 +24,10 @@ import {
|
||||
type TagProps,
|
||||
type TreeInst,
|
||||
type TreeOption,
|
||||
type TreeOverrideNodeClickBehavior,
|
||||
} from 'naive-ui';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { h, nextTick, onMounted, useTemplateRef } from 'vue';
|
||||
import { h, onMounted, useTemplateRef } from 'vue';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { useRoute, useRouter, type LocationQuery } from 'vue-router';
|
||||
import { destr } from 'destr';
|
||||
@@ -49,6 +50,7 @@ const stationStore = useStationStore();
|
||||
const { stationList } = storeToRefs(stationStore);
|
||||
const { data: lineDevices } = useLineDevicesQuery();
|
||||
|
||||
// ========== 设备树数据 ==========
|
||||
const lineDeviceTreeData = computed<Record<string, TreeOption[]>>(() => {
|
||||
const treeData: Record<string, TreeOption[]> = {};
|
||||
deviceTabPanes.forEach(({ name: paneName /* , tab: paneTab */ }) => {
|
||||
@@ -86,7 +88,7 @@ const lineDeviceTreeData = computed<Record<string, TreeOption[]>>(() => {
|
||||
key: nvr.id,
|
||||
suffix: () => `${nvr.ipAddress}`,
|
||||
prefix: () => {
|
||||
return renderDeviceNodePrefix(nvrCluster, stationCode);
|
||||
return renderDeviceNodePrefix(nvr, stationCode);
|
||||
},
|
||||
// 当选择设备时,能获取到设备的所有信息,以及设备所属的车站
|
||||
device: nvr,
|
||||
@@ -152,11 +154,13 @@ const renderDeviceNodePrefix = (device: NdmDeviceResultVO, stationCode: string)
|
||||
return h('div', [renderViewDeviceButton(device, stationCode), renderDeviceStatusTag(device)]);
|
||||
};
|
||||
|
||||
// ========== 选中设备 ==========
|
||||
const selectedTab = ref<DeviceTypeCode>(DeviceType.Camera);
|
||||
const selectedKeys = ref<string[]>();
|
||||
const expandedKeys = ref<string[]>();
|
||||
const selectedDevice = ref<NdmDeviceResultVO>();
|
||||
// 从路由参数中设置选中的设备
|
||||
const setFromRouteQuery = (query: LocationQuery) => {
|
||||
const setDeviceTreePropsFromRouteQuery = (query: LocationQuery) => {
|
||||
const { stationCode, deviceType, deviceDBId } = query;
|
||||
let stnCode = '';
|
||||
let devType: DeviceTypeCode = DeviceType.Camera;
|
||||
@@ -164,6 +168,7 @@ const setFromRouteQuery = (query: LocationQuery) => {
|
||||
if (stationCode) stnCode = stationCode as string;
|
||||
if (deviceType) devType = deviceType as DeviceTypeCode;
|
||||
if (deviceDBId) devDBId = deviceDBId as string;
|
||||
|
||||
selectedTab.value = devType;
|
||||
selectedKeys.value = [devDBId];
|
||||
const stnDevices = lineDevices.value?.[stnCode];
|
||||
@@ -172,35 +177,24 @@ const setFromRouteQuery = (query: LocationQuery) => {
|
||||
selectedDevice.value = devices?.find((device) => device.id === devDBId) ?? selectedDevice.value;
|
||||
};
|
||||
// 页面加载时,需要设置选中的设备
|
||||
onMounted(() => setFromRouteQuery(route.query));
|
||||
onMounted(() => {
|
||||
setDeviceTreePropsFromRouteQuery(route.query);
|
||||
scrollDeviceTreeToSelectedDevice();
|
||||
});
|
||||
// 页面加载时设备数据可能不存在,因此当设备数据更新时,需要重新设置选中的设备
|
||||
watch(lineDevices, () => setFromRouteQuery(route.query), { immediate: true });
|
||||
watch(lineDevices, () => setDeviceTreePropsFromRouteQuery(route.query), { immediate: true });
|
||||
// 更改选择的设备类型时,更新路由查询参数
|
||||
watch(selectedTab, (newTab) => router.replace({ query: { ...route.query, deviceType: newTab } }));
|
||||
// 双击设备时更新路由查询参数
|
||||
const nodeProps = ({ option }: { option: TreeOption }) => {
|
||||
return {
|
||||
ondblclick: () => {
|
||||
if (option['device']) {
|
||||
const device = option['device'] as NdmDeviceResultVO;
|
||||
selectedKeys.value = device.id ? [device.id] : undefined; // 更新选中的树节点
|
||||
selectedDevice.value = device; // 更新选中的设备
|
||||
router.replace({
|
||||
query: {
|
||||
...route.query,
|
||||
stationCode: option['stationCode'] as string,
|
||||
deviceType: selectedTab.value,
|
||||
deviceDBId: device.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
const override: TreeOverrideNodeClickBehavior = ({ option }) => {
|
||||
if (!option['device']) {
|
||||
return 'none';
|
||||
}
|
||||
return 'default';
|
||||
};
|
||||
|
||||
// ========== 设备树搜索 ==========
|
||||
const searchInput = ref('');
|
||||
const statusInput = ref('');
|
||||
|
||||
// 设备树将搜索框和单选框的值都交给NTree的pattern属性
|
||||
// 但是如果一个车站下没有匹配的设备,那么这个车站节点也不会显示
|
||||
const searchPattern = computed(() => {
|
||||
@@ -218,15 +212,22 @@ const searchFilter = (pattern: string, node: TreeOption): boolean => {
|
||||
return searchMatched && statusMatched;
|
||||
};
|
||||
|
||||
// ========== 设备树交互 ==========
|
||||
// 定位到选中的设备
|
||||
const deviceTreeInsts = useTemplateRef<TreeInst[]>('deviceTreeInsts');
|
||||
const onClickLocateDeviceTree = () => {
|
||||
selectedTab.value = (selectedDevice.value?.deviceType ?? selectedTab.value) as DeviceTypeCode;
|
||||
// 等待Tab切换完成后再执行滚动
|
||||
nextTick(() => {
|
||||
selectedKeys.value = selectedDevice.value?.id ? [selectedDevice.value.id] : undefined;
|
||||
expandedKeys.value = route.query['stationCode'] ? [route.query['stationCode'] as string] : undefined;
|
||||
// 由于数据量大所以开启虚拟滚动,
|
||||
// 但是无法知晓NTree内部的虚拟列表容器何时创建完成,所以使用setTimeout延迟固定时间后执行滚动
|
||||
scrollDeviceTreeToSelectedDevice();
|
||||
};
|
||||
const scrollDeviceTreeToSelectedDevice = (timeout: number = 500) => {
|
||||
setTimeout(() => {
|
||||
const inst = deviceTreeInsts.value?.at(0);
|
||||
inst?.scrollTo({ key: selectedDevice.value?.id, behavior: 'smooth' });
|
||||
});
|
||||
}, timeout);
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -252,17 +253,18 @@ const onClickLocateDeviceTree = () => {
|
||||
<NTabs v-model:value="selectedTab" animated type="line" placement="left" style="height: 100%">
|
||||
<NTabPane v-for="pane in deviceTabPanes" :key="pane.name" :name="pane.name" :tab="pane.tab">
|
||||
<NTree
|
||||
:ref="'deviceTreeInsts'"
|
||||
v-model:selected-keys="selectedKeys"
|
||||
v-model:expanded-keys="expandedKeys"
|
||||
:ref="'deviceTreeInsts'"
|
||||
:data="lineDeviceTreeData[pane.name]"
|
||||
:node-props="nodeProps"
|
||||
:show-irrelevant-nodes="false"
|
||||
:pattern="searchPattern"
|
||||
:filter="searchFilter"
|
||||
:override-default-node-click-behavior="override"
|
||||
default-expand-all
|
||||
block-line
|
||||
block-node
|
||||
show-line
|
||||
default-expand-all
|
||||
virtual-scroll
|
||||
style="height: 100%"
|
||||
/>
|
||||
@@ -281,6 +283,7 @@ const onClickLocateDeviceTree = () => {
|
||||
</template>
|
||||
</NPageHeader>
|
||||
<div>selectedKeys: {{ selectedKeys }}</div>
|
||||
<div>expandedKeys: {{ expandedKeys }}</div>
|
||||
<div>selectedDevice: {{ selectedDevice?.deviceId }}</div>
|
||||
<NScrollbar style="width: 500px; height: 400px; border: solid 1px salmon">
|
||||
<pre>{{ selectedDevice }}</pre>
|
||||
|
||||
Reference in New Issue
Block a user