feat: interaction between DashboardPage & DevicePage

This commit is contained in:
yangsy
2025-08-17 03:33:38 +08:00
parent 22f57773e2
commit 9cf72a1734
2 changed files with 73 additions and 10 deletions

View File

@@ -24,5 +24,5 @@ export * from './video/ndm-media-server';
export * from './video/ndm-video-server';
export type NdmDeviceVO = NdmSecurityBoxVO | NdmSwitchVO | NdmNvrVO | NdmCameraVO | NdmDecoderVO | NdmKeyboardVO | NdmMediaServerVO | NdmVideoServerVO;
export type NdmDeviceResultVO = Partial<NdmDeviceVO>;
export type NdmServerVO = NdmMediaServerVO | NdmVideoServerVO;

View File

@@ -1,14 +1,30 @@
<script setup lang="ts">
import type { NdmDeviceVO } from '@/apis/models/device';
import type { NdmDeviceResultVO, NdmDeviceVO } from '@/apis/models/device';
import { useLineDevicesQuery } from '@/composables/query/use-line-devices-query';
import { DeviceType, DeviceTypeName, type DeviceTypeCode } from '@/enums/device-type';
import { DeviceType, DeviceTypeName, type DeviceTypeCode, type DeviceTypeKey } from '@/enums/device-type';
import { useStationStore } from '@/stores/station';
import { ChevronBack } from '@vicons/ionicons5';
import { NIcon, NInput, NLayout, NLayoutContent, NLayoutSider, NPageHeader, NRadio, NRadioGroup, NTabPane, NTabs, NTag, NTree, type TreeOption, type TreeOverrideNodeClickBehavior } from 'naive-ui';
import {
NIcon,
NInput,
NLayout,
NLayoutContent,
NLayoutSider,
NPageHeader,
NRadio,
NRadioGroup,
NScrollbar,
NTabPane,
NTabs,
NTag,
NTree,
type TreeOption,
type TreeOverrideNodeClickBehavior,
} from 'naive-ui';
import { storeToRefs } from 'pinia';
import { h } from 'vue';
import { computed, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { computed, ref, watch } from 'vue';
import { useRoute, useRouter, type LocationQuery } from 'vue-router';
import { destr } from 'destr';
const route = useRoute();
@@ -17,7 +33,7 @@ const router = useRouter();
const onClickBack = () => router.push({ path: `${route.query['from']}` });
const deviceTabPanes = Object.keys(DeviceType).map((key) => {
const name = DeviceType[key as DeviceTypeCode];
const name = DeviceType[key as DeviceTypeKey];
return {
name,
tab: DeviceTypeName[name],
@@ -71,6 +87,49 @@ const lineDeviceTreeData = computed<Record<string, TreeOption[]>>(() => {
return treeData;
});
const selectedTab = ref<DeviceTypeCode>(DeviceType.Camera);
const selectedKeys = ref<string[]>([]);
const selectedDevice = ref<NdmDeviceResultVO>();
const initFromRouteQuery = (query: LocationQuery) => {
const { stationCode, deviceType, deviceId } = query;
let stnCode = '';
let devType: DeviceTypeCode = DeviceType.Camera;
let devId = '';
if (stationCode) stnCode = stationCode as string;
if (deviceType) devType = deviceType as DeviceTypeCode;
if (deviceId) devId = deviceId as string;
selectedTab.value = devType;
selectedKeys.value = [devId];
const stnDevices = lineDevices.value?.[stnCode];
const devices = stnDevices?.[devType];
selectedDevice.value = devices?.find((device) => device.deviceId === deviceId) ?? selectedDevice.value;
};
watch(
() => route.query,
(query) => initFromRouteQuery(query),
{ immediate: true },
);
watch(lineDevices, () => initFromRouteQuery(route.query), { immediate: true });
const nodeProps = ({ option }: { option: TreeOption }) => {
return {
ondblclick: () => {
if (option.isLeaf) {
const device = option['device'] as NdmDeviceResultVO;
selectedDevice.value = device;
router.replace({
query: {
...route.query,
stationCode: option['stationCode'] as string,
deviceType: selectedTab.value,
deviceId: device.deviceId,
},
});
}
},
};
};
watch(selectedTab, (newTab) => router.replace({ query: { ...route.query, deviceType: newTab } }));
const searchInput = ref('');
const statusInput = ref('');
@@ -106,11 +165,13 @@ const searchFilter = (pattern: string, node: TreeOption): boolean => {
</div>
<div style="flex: 1; min-height: 0">
<NTabs animated type="line" placement="left" style="height: 100%">
<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
v-model:selected-keys="selectedKeys"
:data="lineDeviceTreeData[pane.name]"
:override-default-node-click-behavior="override"
:node-props="nodeProps"
:show-irrelevant-nodes="false"
:pattern="searchPattern"
:filter="searchFilter"
@@ -135,8 +196,10 @@ const searchFilter = (pattern: string, node: TreeOption): boolean => {
<div style="font-size: 15px">返回</div>
</template>
</NPageHeader>
<!-- <pre>{{ route.query }}</pre> -->
<pre style="width: 500px; height: 600px; overflow: scroll">{{ lineDeviceTreeData }}</pre>
<div>selectedKeys: {{ selectedKeys }}</div>
<NScrollbar style="width: 500px; height: 400px">
<pre>{{ selectedDevice }}</pre>
</NScrollbar>
<!-- <pre style="width: 500px; height: 100%; overflow: scroll">{{ lineDevices }}</pre> -->
</NLayoutContent>
</NLayout>