some updates

This commit is contained in:
2025-08-13 01:27:07 +08:00
parent fc50dd1127
commit 3f493794fc
3 changed files with 92 additions and 114 deletions

View File

@@ -2,15 +2,13 @@ import type { FC } from 'react';
import { AlertOutlined, ApiOutlined } from '@ant-design/icons';
import { Card, Col, Row, Statistic, Tag } from 'antd';
import { useState } from 'react';
import { useMemo } from 'react';
import type { NdmCameraResultVO, NdmDecoderResultVO, NdmDeviceAlarmLogResultVO, NdmKeyboardResultVO, NdmMediaServerResultVO, NdmNvrResultVO, NdmSecurityBoxResultVO, NdmSwitchResultVO, NdmVideoServerResultVO } from '@/apis/models/device';
interface StationProps {
name: string;
online: boolean;
// offlineDeviceCount: number;
// alarmCount: number;
ndmCameraList: NdmCameraResultVO[];
ndmDecoderList: NdmDecoderResultVO[];
ndmKeyboardList: NdmKeyboardResultVO[];
@@ -23,25 +21,24 @@ interface StationProps {
}
export const Station: FC<StationProps> = ({ name, online, ndmCameraList, ndmDecoderList, ndmKeyboardList, ndmMediaServerList, ndmNvrList, ndmSecurityBoxList, ndmSwitchList, ndmVideoServerList, ndmDeviceAlarmLogList }) => {
const [offlineDeviceCount] = useState(12);
const [alarmCount] = useState(3);
// 使用 useMemo 计算离线设备数量
const offlineDeviceCount = useMemo(() => {
const offlineCameraCount = ndmCameraList.filter(device => device.deviceStatus === '20').length;
const offlineDecoderCount = ndmDecoderList.filter(device => device.deviceStatus === '20').length;
const offlineKeyboardCount = ndmKeyboardList.filter(device => device.deviceStatus === '20').length;
const offlineMediaServerCount = ndmMediaServerList.filter(device => device.deviceStatus === '20').length;
const offlineNvrCount = ndmNvrList.filter(device => device.deviceStatus === '20').length;
const offlineSecurityBoxCount = ndmSecurityBoxList.filter(device => device.deviceStatus === '20').length;
const offlineSwitchCount = ndmSwitchList.filter(device => device.deviceStatus === '20').length;
const offlineVideoServerCount = ndmVideoServerList.filter(device => device.deviceStatus === '20').length;
const offlineCameraCount = ndmCameraList.filter(device => device.deviceStatus === '20').length;
const cameraCount = ndmCameraList.length;
const offlineDecoderCount = ndmDecoderList.filter(device => device.deviceStatus === '20').length;
const decoderCount = ndmDecoderList.length;
const offlineKeyboardCount = ndmKeyboardList.filter(device => device.deviceStatus === '20').length;
const keyboardCount = ndmKeyboardList.length;
const offlineMediaServerCount = ndmMediaServerList.filter(device => device.deviceStatus === '20').length;
const mediaServerCount = ndmMediaServerList.length;
const offlineNvrCount = ndmNvrList.filter(device => device.deviceStatus === '20').length;
const nvrCount = ndmNvrList.length;
const offlineSecurityBoxCount = ndmSecurityBoxList.filter(device => device.deviceStatus === '20').length;
const securityBoxCount = ndmSecurityBoxList.length;
const switchOfflineCount = ndmSwitchList.filter(device => device.deviceStatus === '20').length;
const switchCount = ndmSwitchList.length;
const offlineVideoServerCount = ndmVideoServerList.filter(device => device.deviceStatus === '20').length;
const videoServerCount = ndmVideoServerList.length;
return offlineCameraCount + offlineDecoderCount + offlineKeyboardCount + offlineMediaServerCount + offlineNvrCount + offlineSecurityBoxCount + offlineSwitchCount + offlineVideoServerCount;
}, [ndmCameraList, ndmDecoderList, ndmKeyboardList, ndmMediaServerList, ndmNvrList, ndmSecurityBoxList, ndmSwitchList, ndmVideoServerList]);
// 使用 useMemo 计算告警数量
const alarmCount = useMemo(() => {
return ndmDeviceAlarmLogList.length;
}, [ndmDeviceAlarmLogList]);
return (
<Card
@@ -50,26 +47,24 @@ export const Station: FC<StationProps> = ({ name, online, ndmCameraList, ndmDeco
styles={{ header: name.length > 7 ? { fontSize: '12px' } : {} }}
extra={<Tag color={online ? 'success' : 'error'}>{online ? '在线' : '离线'}</Tag>}
>
{online && (
<Row gutter={16}>
<Col span={12}>
<Statistic
title={<span style={{ cursor: 'pointer', textDecoration: 'underline dotted' }}>线</span>}
value={offlineDeviceCount}
prefix={<ApiOutlined />}
valueStyle={{ color: offlineDeviceCount > 0 ? '#cf1322' : undefined }}
/>
</Col>
<Col span={12}>
<Statistic
title={<span style={{ cursor: 'pointer', textDecoration: 'underline dotted' }}></span>}
value={alarmCount}
prefix={<AlertOutlined />}
valueStyle={{ color: alarmCount > 0 ? '#faad14' : undefined }}
/>
</Col>
</Row>
)}
<Row gutter={16}>
<Col span={12}>
<Statistic
title={<span style={{ cursor: 'pointer', textDecoration: 'underline dotted' }}>线</span>}
value={online ? offlineDeviceCount : ''}
prefix={<ApiOutlined size={12} />}
valueStyle={{ color: offlineDeviceCount > 0 ? '#cf1322' : undefined }}
/>
</Col>
<Col span={12}>
<Statistic
title={<span style={{ cursor: 'pointer', textDecoration: 'underline dotted' }}></span>}
value={online ? alarmCount : ''}
prefix={<AlertOutlined />}
valueStyle={{ color: alarmCount > 0 ? '#faad14' : undefined }}
/>
</Col>
</Row>
</Card>
);
};

View File

@@ -1,17 +1,15 @@
import { useQuery } from '@tanstack/react-query';
import type { Station } from '@/apis/domains';
import type { PageResult } from '@/apis/models/base/page';
import type { DefParameterResultVO } from '@/apis/models/system';
import { ndmClient, userClient } from '@/apis/client';
import { ndmVerify, postDefParameterPage } from '@/apis/requests';
export function useStationListQuery() {
return useQuery({
queryKey: ['station-list'],
queryKey: ['station-list-polling'],
queryFn: async () => {
// 第一步:获取车站基础信息
const [err, data] = await userClient.post<PageResult<DefParameterResultVO>>(`/api/system/defParameter/page`, {
const { records: ndmStationList } = await postDefParameterPage('', {
current: 1,
extra: {},
model: {
@@ -21,12 +19,9 @@ export function useStationListQuery() {
size: 100,
sort: 'id',
});
if (err || !data) {
throw err;
}
// 第二步:获取每个车站的在线状态
const stations: Station[] = data.records.map(record => ({
const stations: Station[] = ndmStationList.map(record => ({
id: record.key ?? '',
code: record.value ?? '',
name: record.name ?? '',
@@ -34,9 +29,7 @@ export function useStationListQuery() {
}));
// 第三步:并发检查所有车站的在线状态
const pingResultList = await Promise.allSettled(stations.map((station) => {
return ndmClient.post(`/${station.code}/api/ndm/ndmKeepAlive/verify`, {}, { timeout: 5000 });
}));
const pingResultList = await Promise.allSettled(stations.map(station => ndmVerify(station.code)));
// 第四步:合并状态信息
const stationsWithStatus: Station[] = stations.map((station, index) => ({

View File

@@ -2,6 +2,8 @@ import { useQuery } from '@tanstack/react-query';
import { createFileRoute } from '@tanstack/react-router';
import { Col, Row } from 'antd';
import type { PageParams } from '@/apis/models/base/page';
import {
postNdmCameraPage,
postNdmDecoderPage,
@@ -11,7 +13,7 @@ import {
postNdmSecurityBoxPage,
postNdmSwitchPage,
postNdmVideoServerPage,
} from '@/apis/requests/device';
} from '@/apis/requests';
import { Station } from '@/components/dashboard/station';
import { useStationStore } from '@/store/station';
@@ -21,80 +23,68 @@ export const Route = createFileRoute('/_app/dashboard')({
function DashboardPage() {
const stationList = useStationStore(state => state.stationList);
const onlineStationList = stationList.filter(station => station.online);
const { data } = useQuery({
queryKey: ['device-list', 'all-type', onlineStationList.map(s => s.code)],
queryFn: async () => {
const pageQuery = { model: {}, extra: {}, size: 5000, current: 1, sort: 'id', order: 'ascending' as const };
const stationDevicePromises = onlineStationList.map(async (station) => {
const deviceRequests = [
postNdmCameraPage(station.code, pageQuery),
postNdmDecoderPage(station.code, pageQuery),
postNdmKeyboardPage(station.code, pageQuery),
postNdmMediaServerPage(station.code, pageQuery),
postNdmNvrPage(station.code, pageQuery),
postNdmSecurityBoxPage(station.code, pageQuery),
postNdmSwitchPage(station.code, pageQuery),
postNdmVideoServerPage(station.code, pageQuery),
];
const results = await Promise.all(deviceRequests);
const [
[, cameraData],
[, decoderData],
[, keyboardData],
[, mediaServerData],
[, nvrData],
[, securityBoxData],
[, switchData],
[, videoServerData],
] = results;
return {
stationCode: station.code,
ndmCameraList: cameraData?.records ?? [],
ndmDecoderList: decoderData?.records ?? [],
ndmKeyboardList: keyboardData?.records ?? [],
ndmMediaServerList: mediaServerData?.records ?? [],
ndmNvrList: nvrData?.records ?? [],
ndmSecurityBoxList: securityBoxData?.records ?? [],
ndmSwitchList: switchData?.records ?? [],
ndmVideoServerList: videoServerData?.records ?? [],
};
});
const allStationsData = await Promise.all(stationDevicePromises);
return allStationsData.reduce((acc, result) => {
acc[result.stationCode] = result;
return acc;
}, {} as Record<string, typeof allStationsData[number]>);
},
const { data, error } = useQuery({
enabled: onlineStationList.length > 0,
queryKey: ['station-list', 'device-list'],
queryFn: async () => {
const pageQuery: PageParams<{}> = {
model: {},
extra: {},
size: 5000,
current: 1,
sort: 'id',
order: 'ascending',
};
const result: Record<string, any> = {};
for (const station of onlineStationList) {
const { records: ndmCameraList } = await postNdmCameraPage(station.code, pageQuery);
console.log('ndmCameraList:', ndmCameraList);
// const { records: ndmDecoderList } = await postNdmDecoderPage(station.code, pageQuery);
// console.log('ndmDecoderList:', ndmDecoderList);
// const { records: ndmKeyboardList } = await postNdmKeyboardPage(station.code, pageQuery);
// console.log('ndmKeyboardList:', ndmKeyboardList);
// const { records: ndmMediaServerList } = await postNdmMediaServerPage(station.code, pageQuery);
// console.log('ndmMediaServerList:', ndmMediaServerList);
// const { records: ndmNvrList } = await postNdmNvrPage(station.code, pageQuery);
// console.log('ndmNvrList:', ndmNvrList);
// const { records: ndmSecurityBoxList } = await postNdmSecurityBoxPage(station.code, pageQuery);
// console.log('ndmSecurityBoxList:', ndmSecurityBoxList);
// const { records: ndmSwitchList } = await postNdmSwitchPage(station.code, pageQuery);
// console.log('ndmSwitchList:', ndmSwitchList);
// const { records: ndmVideoServerList } = await postNdmVideoServerPage(station.code, pageQuery);
// console.log('ndmVideoServerList:', ndmVideoServerList);
result[station.code] = {
ndmCameraList,
};
}
return result;
},
});
if (error) {
return <pre>{JSON.stringify(error, null, 2)}</pre>;
}
return (
<div style={{ padding: '6px' }}>
<pre>{JSON.stringify(data, null, 2)}</pre>
<Row gutter={[6, 6]}>
{stationList.map((station) => {
const deviceData = data?.[station.code];
return (
<Col key={station.id} span={3}>
<Station
name={station.name}
online={station.online}
ndmCameraList={deviceData?.ndmCameraList ?? []}
ndmDecoderList={deviceData?.ndmDecoderList ?? []}
ndmKeyboardList={deviceData?.ndmKeyboardList ?? []}
ndmMediaServerList={deviceData?.ndmMediaServerList ?? []}
ndmNvrList={deviceData?.ndmNvrList ?? []}
ndmSecurityBoxList={deviceData?.ndmSecurityBoxList ?? []}
ndmSwitchList={deviceData?.ndmSwitchList ?? []}
ndmVideoServerList={deviceData?.ndmVideoServerList ?? []}
ndmCameraList={[]}
ndmDecoderList={[]}
ndmKeyboardList={[]}
ndmMediaServerList={[]}
ndmNvrList={[]}
ndmSecurityBoxList={[]}
ndmSwitchList={[]}
ndmVideoServerList={[]}
ndmDeviceAlarmLogList={[]}
/>
</Col>