1 Commits

Author SHA1 Message Date
yangsy 68a6d48e71 release: v0.41.0 2026-05-19 19:43:09 +08:00
14 changed files with 37 additions and 262 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "ndm-web-platform",
"version": "0.42.0",
"version": "0.41.0",
"private": true,
"type": "module",
"engines": {
-16
View File
@@ -1,20 +1,4 @@
[
{
"version": "0.42.0",
"date": "2026-05-20",
"changes": {
"fixes": [
{ "content": "优化安防箱环境数据卡片,避免空标签渲染并改进风扇信息展示" },
{ "content": "修复设备硬件卡片进度条异常值显示问题,并完善状态判断逻辑" }
],
"feats": [
{ "content": "新增服务器网卡信息展示" },
{ "content": "新增安防箱网卡信息展示,并优化相关卡片标题" },
{ "content": "为交换机诊断信息新增温度字段" },
{ "content": "新增录像机环境状态卡片和网卡信息展示" }
]
}
},
{
"version": "0.41.0",
"date": "2026-05-19",
+2 -2
View File
@@ -1,4 +1,4 @@
{
"version": "0.42.0",
"buildTime": "2026-05-20 13:52:07"
"version": "0.41.0",
"buildTime": "2026-05-19 19:40:37"
}
+8 -43
View File
@@ -10,37 +10,6 @@ export interface NdmNvrDiagInfo {
totalSize?: number;
}[];
};
ethInfo: {
adminStatus?: string; // '1'
desc?: string; // 'bond1'
ifType?: string; // '6'
inDiscards?: string; // '17931688'
inErrors?: string; // '0'
inNUcastPkts?: string; // '40945433'
inOctets?: string; // '3453544614'
inUcastPkts?: string; // '3375411816'
inUnknownProtos?: string; // '0'
index?: string; // '8'
lastChange?: string; // '0:05:42.15'
mTU?: string; // '1500'
macAddress?: string; // '04:7b:cb:69:92:58'
operStatus?: string; // '1'
outDiscards?: string; // '0'
outErrors?: string; // '0'
outNUcastPkts?: string; // '0'
outOctets?: string; // '3443476717'
outQLen?: string; // '0'
outUcastPkts?: string; // '415381735'
specific?: string; // '0.0'
speed?: string; // '2000000000'
};
ipInfo: {
broadcastAddress?: string; // '1'
iPAddress?: string; // '10.14.1.22'
index?: string; // '8'
mASK?: string; // '255.255.255.0'
reasmMaxSize?: string; // '0'
};
stCommonInfo?: {
设备ID?: string;
软件版本?: string;
@@ -51,16 +20,12 @@ export interface NdmNvrDiagInfo {
内存使用率?: string;
CPU使用率?: string;
};
cdFanInfo?: NdmNvrFanInfo[];
cdPowerSupplyInfo?: NdmNvrPowerSupplyInfo[];
}
export interface NdmNvrFanInfo {
索引号?: string;
'风扇转速(rpm)'?: string;
}
export interface NdmNvrPowerSupplyInfo {
索引号?: string;
电源状态?: string;
cdFanInfo?: {
索引号?: string;
'风扇转速(rpm)'?: string;
}[];
cdPowerSupplyInfo?: {
索引号?: string;
电源状态?: string;
}[];
}
@@ -1,36 +1,5 @@
export interface NdmSecurityBoxDiagInfo {
[key: string]: any;
ethInfo?: {
adminStatus?: string; // '1'
desc?: string; // 'br-lan'
ifType?: string; // '6'
inDiscards?: string; // '84977'
inErrors?: string; // '0'
inNUcastPkts?: string; // '233473'
inOctets?: string; // '92355850'
inUcastPkts?: string; // '899970'
inUnknownProtos?: string; // '0'
index?: string; // '8'
lastChange?: string; // '0:00:00.00'
mTU?: string; // '1500'
macAddress?: string; // '56:62:bc:d3:9e:37'
operStatus?: string; // '1'
outDiscards?: string; // '0'
outErrors?: string; // '0'
outNUcastPkts?: string; // '0'
outOctets?: string; // '68175904'
outQLen?: string; // '0'
outUcastPkts?: string; // '748100'
specific?: string; // '0.0'
speed?: string; // '0'
};
ipInfo?: {
broadcastAddress?: string; // '1'
iPAddress?: string; // '10.24.18.101'
index?: string; // '8'
mASK?: string; // '255.255.255.0'
reasmMaxSize?: string; // '0'
};
info?: [
{
addrCode?: number;
@@ -6,35 +6,4 @@ export interface NdmServerDiagInfo {
磁盘使用率?: string;
系统运行时间?: string;
};
ethInfo?: {
adminStatus?: string; // '1'
desc?: string; // 'Intel Corporation I350 Gigabit Network Connection'
ifType?: string; // '6'
inDiscards?: string; // '6707634'
inErrors?: string; // '0'
inNUcastPkts?: string; // '8991944'
inOctets?: string; // '4220524983'
inUcastPkts?: string; // '2342740610'
inUnknownProtos?: string; // '0'
index?: string; // '2'
lastChange?: string; // '0:03:15.26'
mTU?: string; // '1500'
macAddress?: string; // 'e8:78:ee:f6:8d:98'
operStatus?: string; // '1'
outDiscards?: string; // '0'
outErrors?: string; // '0'
outNUcastPkts?: string; // '0'
outOctets?: string; // '1415770066'
outQLen?: string; // '0'
outUcastPkts?: string; // '3335494729'
specific?: string; // '0.0'
speed?: string; // '1000000000'
};
ipInfo?: {
broadcastAddress?: string; // '1'
iPAddress?: string; // '10.14.1.8'
index?: string; // '2'
mASK?: string; // '255.255.255.0'
reasmMaxSize?: string; // '0'
};
}
@@ -2,7 +2,6 @@ export interface NdmSwitchDiagInfo {
[key: string]: any;
cpuRatio?: string; // 因环境不同可能不存在
memoryRatio?: string; // 因环境不同可能不存在
temperature?: number;
logTime?: string;
info?: {
overFlowPorts?: string[];
@@ -51,13 +51,8 @@ const formattedRunningTime = computed(() => {
return (runningTime?.value ?? '-').replace('days', '天');
});
const getProgressPercentage = (percent: number) => {
if (percent < 0) return 0;
if (percent > 100) return 100;
return percent;
};
const getProgressStatus = (percent: number): ProgressStatus => {
const getProgressStatus = (percent?: number): ProgressStatus | undefined => {
if (!percent) return undefined;
if (percent >= 90) return 'error';
if (percent >= 70) return 'warning';
return 'success';
@@ -71,20 +66,20 @@ const getProgressStatus = (percent: number): ProgressStatus => {
</template>
<template #default>
<NFlex vertical>
<NFlex v-if="cpuPercent" style="width: 100%" align="center" :wrap="false">
<NFlex v-if="cpuUsage" style="width: 100%" align="center" :wrap="false">
<NIcon :component="CpuIcon" />
<span style="word-break: keep-all">{{ cpuUsageLabel || 'CPU' }}</span>
<NProgress :percentage="getProgressPercentage(cpuPercent)" :status="getProgressStatus(cpuPercent)">{{ cpuPercent }}%</NProgress>
<NProgress :percentage="cpuPercent" :status="getProgressStatus(cpuPercent)">{{ cpuPercent ?? '-' }}%</NProgress>
</NFlex>
<NFlex v-if="memPercent" style="width: 100%" align="center" :wrap="false">
<NFlex v-if="memUsage" style="width: 100%" align="center" :wrap="false">
<NIcon :component="MemoryStickIcon" />
<span style="word-break: keep-all">{{ memUsageLabel || '内存' }}</span>
<NProgress :percentage="getProgressPercentage(memPercent)" :status="getProgressStatus(memPercent)">{{ memPercent }}%</NProgress>
<NProgress :percentage="memPercent" :status="getProgressStatus(memPercent)">{{ memPercent ?? '-' }}%</NProgress>
</NFlex>
<NFlex v-if="diskPercent" style="width: 100%" align="center" :wrap="false">
<NFlex v-if="diskUsage" style="width: 100%" align="center" :wrap="false">
<NIcon :component="HardDriveIcon" />
<span style="word-break: keep-all">{{ diskUsageLabel || '磁盘' }}</span>
<NProgress :percentage="getProgressPercentage(diskPercent)" :status="getProgressStatus(diskPercent)">{{ diskPercent }}%</NProgress>
<NProgress :percentage="diskPercent" :status="getProgressStatus(diskPercent)">{{ diskPercent ?? '-' }}%</NProgress>
</NFlex>
<NFlex v-if="runningTime" style="width: 100%" align="center" :wrap="false">
<NIcon :component="ClockCheckIcon" />
@@ -2,7 +2,6 @@ import type { ComponentInstance } from 'vue';
import DeviceCommonCard from './device-common-card.vue';
import DeviceHardwareCard from './device-hardware-card.vue';
import DeviceHeaderCard from './device-header-card.vue';
import NvrEnvCard from './nvr-env-card.vue';
import NvrDiskCard from './nvr-disk-card.vue';
import NvrRecordCheckCard from './nvr-record-check-card.vue';
import SecurityBoxCircuitCard from './security-box-circuit-card.vue';
@@ -17,7 +16,6 @@ export {
DeviceCommonCard,
DeviceHardwareCard,
DeviceHeaderCard,
NvrEnvCard,
NvrDiskCard,
NvrRecordCheckCard,
SecurityBoxCircuitCard,
@@ -1,47 +0,0 @@
<script setup lang="ts">
import type { NdmNvrFanInfo, NdmNvrPowerSupplyInfo } from '@/apis';
import { FanIcon, PlugIcon } from 'lucide-vue-next';
import { NCard, NFlex, NIcon, NTag } from 'naive-ui';
import { computed, toRefs } from 'vue';
const props = defineProps<{
fanInfo?: NdmNvrFanInfo[];
powerSupplyInfo?: NdmNvrPowerSupplyInfo[];
}>();
const { fanInfo, powerSupplyInfo } = toRefs(props);
const showCard = computed(() => {
return Object.values(props).some((value) => !!value);
});
</script>
<template>
<NCard v-if="showCard" hoverable size="small">
<template #header>
<span>录像机环境状态</span>
</template>
<template #default>
<NFlex vertical>
<NTag v-for="info in fanInfo ?? []" :key="info['索引号']">
<template #icon>
<NIcon :component="FanIcon" />
</template>
<template #default>
<span>风扇{{ info['索引号'] }}: {{ info['风扇转速(rpm)'] }} RPM</span>
</template>
</NTag>
<NTag v-for="info in powerSupplyInfo ?? []" :key="info['索引号']">
<template #icon>
<NIcon :component="PlugIcon" />
</template>
<template #default>
<span>电源{{ info['索引号'] }}: {{ info['电源状态'] }}</span>
</template>
</NTag>
</NFlex>
</template>
</NCard>
</template>
<style scoped></style>
@@ -35,16 +35,21 @@ const getStatusTagType = (status: string | null) => {
if (['失效', '开门'].includes(status ?? '')) return 'error';
return 'default';
};
const formattedFanSpeeds = computed(() => {
if (!fanSpeeds?.value || fanSpeeds.value.length === 0) return null;
return fanSpeeds.value.map((speed, index) => `风扇${index + 1}: ${speed} RPM`).join(', ');
});
</script>
<template>
<NCard v-if="showCard" hoverable size="small">
<template #header>
<span>安防箱环境状态</span>
<span>安防箱状态</span>
</template>
<template #default>
<NFlex vertical>
<NTag v-if="!!temperature">
<NTag>
<template #icon>
<NIcon :component="ThermometerIcon" />
</template>
@@ -52,7 +57,7 @@ const getStatusTagType = (status: string | null) => {
<span>温度: {{ temperature }}</span>
</template>
</NTag>
<NTag v-if="!!humidity">
<NTag>
<template #icon>
<NIcon :component="DropletIcon" />
</template>
@@ -60,15 +65,15 @@ const getStatusTagType = (status: string | null) => {
<span>湿度: {{ humidity }}%</span>
</template>
</NTag>
<NTag v-for="(speed, index) in fanSpeeds ?? []" :key="index">
<NTag>
<template #icon>
<NIcon :component="FanIcon" />
</template>
<template #default>
<span>风扇{{ index + 1 }}: {{ speed }} RPM</span>
<span>风扇: {{ formattedFanSpeeds }}</span>
</template>
</NTag>
<NTag v-if="!!accessControlStatus" :type="getStatusTagType(accessControlStatus)">
<NTag :type="getStatusTagType(accessControlStatus)">
<template #icon>
<NIcon :component="ShieldIcon" />
</template>
@@ -76,7 +81,7 @@ const getStatusTagType = (status: string | null) => {
<span>门禁: {{ accessControlStatus }}</span>
</template>
</NTag>
<NTag v-if="!!lightningProtectionStatus" :type="getStatusTagType(lightningProtectionStatus)">
<NTag :type="getStatusTagType(lightningProtectionStatus)">
<template #icon>
<NIcon :component="ZapIcon" />
</template>
@@ -1,6 +1,6 @@
<script setup lang="ts">
import type { NdmNvrDiagInfo, NdmNvrResultVO, Station } from '@/apis';
import { DeviceCommonCard, DeviceHardwareCard, DeviceHeaderCard, NvrDiskCard, NvrEnvCard, NvrRecordCheckCard, type DeviceCommonCardProps } from '@/components';
import { DeviceCommonCard, DeviceHardwareCard, DeviceHeaderCard, NvrDiskCard, NvrRecordCheckCard, type DeviceCommonCardProps } from '@/components';
import { isNvrCluster } from '@/helpers';
import destr from 'destr';
import { NFlex } from 'naive-ui';
@@ -21,14 +21,9 @@ const lastDiagInfo = computed(() => {
});
const commonInfo = computed<DeviceCommonCardProps['commonInfo']>(() => {
const { ipAddress } = ndmDevice.value;
const { ethInfo, ipInfo, stCommonInfo } = lastDiagInfo.value ?? {};
const { 设备ID, 软件版本, 生产厂商, 设备别名, 设备型号, 硬件版本 } = stCommonInfo ?? {};
let operStatus = '-';
if (!!ethInfo?.operStatus) {
operStatus = ethInfo?.operStatus === '1' ? '正常' : '异常';
}
const { stCommonInfo } = lastDiagInfo.value ?? {};
if (!stCommonInfo) return undefined;
const { 设备ID, 软件版本, 生产厂商, 设备别名, 设备型号, 硬件版本 } = stCommonInfo;
return [
{
@@ -42,17 +37,6 @@ const commonInfo = computed<DeviceCommonCardProps['commonInfo']>(() => {
{ label: '硬件版本', value: 硬件版本 || '-' },
],
},
{
title: '设备网卡信息',
items: [
{ label: 'IP地址', value: ipAddress || '-' },
{ label: '子网掩码', value: ipInfo?.mASK || '-' },
{ label: 'MAC地址', value: ethInfo?.macAddress || '-' },
{ label: '连接速率', value: ethInfo?.speed || '-' },
{ label: 'MTU', value: ethInfo?.mTU || '-' },
{ label: '运行状态', value: operStatus },
],
},
];
});
@@ -61,9 +45,6 @@ const memUsage = computed(() => lastDiagInfo.value?.stCommonInfo?.内存使用
const diskHealth = computed(() => lastDiagInfo.value?.info?.diskHealth);
const diskArray = computed(() => lastDiagInfo.value?.info?.groupInfoList);
const fanInfo = computed(() => lastDiagInfo.value?.cdFanInfo);
const powerSupplyInfo = computed(() => lastDiagInfo.value?.cdPowerSupplyInfo);
</script>
<template>
@@ -71,7 +52,6 @@ const powerSupplyInfo = computed(() => lastDiagInfo.value?.cdPowerSupplyInfo);
<DeviceHeaderCard :ndm-device="ndmDevice" :station="station" />
<DeviceCommonCard :common-info="commonInfo" />
<DeviceHardwareCard :cpu-usage="cpuUsage" :mem-usage="memUsage" />
<NvrEnvCard :fan-info="fanInfo" :power-supply-info="powerSupplyInfo" />
<NvrDiskCard :disk-health="diskHealth" :disk-array="diskArray" />
<template v-if="isNvrCluster(ndmDevice)">
<NvrRecordCheckCard :ndm-device="ndmDevice" :station="station" />
@@ -35,15 +35,9 @@ const vendor = computed(() => {
});
const commonInfo = computed<DeviceCommonCardProps['commonInfo']>(() => {
const { ipAddress } = ndmDevice.value;
const { ethInfo, ipInfo, stCommonInfo } = lastDiagInfo.value ?? {};
const { stCommonInfo } = lastDiagInfo.value ?? {};
const { 设备ID, 软件版本, 设备厂商, 设备别名, 设备型号, 硬件版本 } = stCommonInfo ?? {};
let operStatus = '-';
if (!!ethInfo?.operStatus) {
operStatus = ethInfo?.operStatus === '1' ? '正常' : '异常';
}
return [
{
title: '设备型号信息',
@@ -56,17 +50,6 @@ const commonInfo = computed<DeviceCommonCardProps['commonInfo']>(() => {
{ label: '硬件版本', value: 硬件版本 || '-' },
],
},
{
title: '设备网卡信息',
items: [
{ label: 'IP地址', value: ipAddress || '-' },
{ label: '子网掩码', value: ipInfo?.mASK || '-' },
{ label: 'MAC地址', value: ethInfo?.macAddress || '-' },
{ label: '连接速率', value: ethInfo?.speed || '-' },
{ label: 'MTU', value: ethInfo?.mTU || '-' },
{ label: '运行状态', value: operStatus },
],
},
];
});
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { type NdmServerDiagInfo, type NdmServerResultVO, type Station } from '@/apis';
import { DeviceCommonCard, DeviceHardwareCard, DeviceHeaderCard, ServerAlive, ServerHighAvailable, ServerStreamPush, type DeviceCommonCardProps } from '@/components';
import { DeviceHardwareCard, DeviceHeaderCard, ServerAlive, ServerHighAvailable, ServerStreamPush } from '@/components';
import destr from 'destr';
import { NFlex } from 'naive-ui';
import { computed, toRefs } from 'vue';
@@ -19,30 +19,6 @@ const lastDiagInfo = computed(() => {
return result as NdmServerDiagInfo;
});
const commonInfo = computed<DeviceCommonCardProps['commonInfo']>(() => {
const { ipAddress } = ndmDevice.value;
const { ethInfo, ipInfo } = lastDiagInfo.value ?? {};
let operStatus = '-';
if (!!ethInfo?.operStatus) {
operStatus = ethInfo?.operStatus === '1' ? '正常' : '异常';
}
return [
{
title: '设备网卡信息',
items: [
{ label: 'IP地址', value: ipAddress || '-' },
{ label: '子网掩码', value: ipInfo?.mASK || '-' },
{ label: 'MAC地址', value: ethInfo?.macAddress || '-' },
{ label: '连接速率', value: ethInfo?.speed || '-' },
{ label: 'MTU', value: ethInfo?.mTU || '-' },
{ label: '运行状态', value: operStatus },
],
},
];
});
const cpuUsage = computed(() => lastDiagInfo.value?.commInfo?.CPU使用率);
const memUsage = computed(() => lastDiagInfo.value?.commInfo?.内存使用率);
const diskUsage = computed(() => lastDiagInfo.value?.commInfo?.磁盘使用率);
@@ -53,7 +29,6 @@ const runningTime = computed(() => lastDiagInfo.value?.commInfo?.系统运行时
<NFlex vertical>
<ServerHighAvailable :ndm-device="ndmDevice" :station="station" />
<DeviceHeaderCard :ndm-device="ndmDevice" :station="station" />
<DeviceCommonCard :common-info="commonInfo" />
<DeviceHardwareCard running-time-label="服务器运行时间" :cpu-usage="cpuUsage" :mem-usage="memUsage" :disk-usage="diskUsage" :running-time="runningTime" />
<ServerAlive :ndm-device="ndmDevice" :station="station" />
<ServerStreamPush :ndm-device="ndmDevice" :station="station" />