feat: interaction between DashboardPage & DevicePage
This commit is contained in:
@@ -24,5 +24,5 @@ export * from './video/ndm-media-server';
|
|||||||
export * from './video/ndm-video-server';
|
export * from './video/ndm-video-server';
|
||||||
|
|
||||||
export type NdmDeviceVO = NdmSecurityBoxVO | NdmSwitchVO | NdmNvrVO | NdmCameraVO | NdmDecoderVO | NdmKeyboardVO | NdmMediaServerVO | NdmVideoServerVO;
|
export type NdmDeviceVO = NdmSecurityBoxVO | NdmSwitchVO | NdmNvrVO | NdmCameraVO | NdmDecoderVO | NdmKeyboardVO | NdmMediaServerVO | NdmVideoServerVO;
|
||||||
|
export type NdmDeviceResultVO = Partial<NdmDeviceVO>;
|
||||||
export type NdmServerVO = NdmMediaServerVO | NdmVideoServerVO;
|
export type NdmServerVO = NdmMediaServerVO | NdmVideoServerVO;
|
||||||
|
|||||||
@@ -1,14 +1,30 @@
|
|||||||
<script setup lang="ts">
|
<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 { 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 { useStationStore } from '@/stores/station';
|
||||||
import { ChevronBack } from '@vicons/ionicons5';
|
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 { storeToRefs } from 'pinia';
|
||||||
import { h } from 'vue';
|
import { h } from 'vue';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref, watch } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter, type LocationQuery } from 'vue-router';
|
||||||
import { destr } from 'destr';
|
import { destr } from 'destr';
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -17,7 +33,7 @@ const router = useRouter();
|
|||||||
const onClickBack = () => router.push({ path: `${route.query['from']}` });
|
const onClickBack = () => router.push({ path: `${route.query['from']}` });
|
||||||
|
|
||||||
const deviceTabPanes = Object.keys(DeviceType).map((key) => {
|
const deviceTabPanes = Object.keys(DeviceType).map((key) => {
|
||||||
const name = DeviceType[key as DeviceTypeCode];
|
const name = DeviceType[key as DeviceTypeKey];
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
tab: DeviceTypeName[name],
|
tab: DeviceTypeName[name],
|
||||||
@@ -71,6 +87,49 @@ const lineDeviceTreeData = computed<Record<string, TreeOption[]>>(() => {
|
|||||||
return treeData;
|
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 searchInput = ref('');
|
||||||
const statusInput = ref('');
|
const statusInput = ref('');
|
||||||
|
|
||||||
@@ -106,11 +165,13 @@ const searchFilter = (pattern: string, node: TreeOption): boolean => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="flex: 1; min-height: 0">
|
<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">
|
<NTabPane v-for="pane in deviceTabPanes" :key="pane.name" :name="pane.name" :tab="pane.tab">
|
||||||
<NTree
|
<NTree
|
||||||
|
v-model:selected-keys="selectedKeys"
|
||||||
:data="lineDeviceTreeData[pane.name]"
|
:data="lineDeviceTreeData[pane.name]"
|
||||||
:override-default-node-click-behavior="override"
|
:override-default-node-click-behavior="override"
|
||||||
|
:node-props="nodeProps"
|
||||||
:show-irrelevant-nodes="false"
|
:show-irrelevant-nodes="false"
|
||||||
:pattern="searchPattern"
|
:pattern="searchPattern"
|
||||||
:filter="searchFilter"
|
:filter="searchFilter"
|
||||||
@@ -135,8 +196,10 @@ const searchFilter = (pattern: string, node: TreeOption): boolean => {
|
|||||||
<div style="font-size: 15px">返回</div>
|
<div style="font-size: 15px">返回</div>
|
||||||
</template>
|
</template>
|
||||||
</NPageHeader>
|
</NPageHeader>
|
||||||
<!-- <pre>{{ route.query }}</pre> -->
|
<div>selectedKeys: {{ selectedKeys }}</div>
|
||||||
<pre style="width: 500px; height: 600px; overflow: scroll">{{ lineDeviceTreeData }}</pre>
|
<NScrollbar style="width: 500px; height: 400px">
|
||||||
|
<pre>{{ selectedDevice }}</pre>
|
||||||
|
</NScrollbar>
|
||||||
<!-- <pre style="width: 500px; height: 100%; overflow: scroll">{{ lineDevices }}</pre> -->
|
<!-- <pre style="width: 500px; height: 100%; overflow: scroll">{{ lineDevices }}</pre> -->
|
||||||
</NLayoutContent>
|
</NLayoutContent>
|
||||||
</NLayout>
|
</NLayout>
|
||||||
|
|||||||
Reference in New Issue
Block a user