refactor: move /helper
This commit is contained in:
@@ -1,81 +1,15 @@
|
||||
<script setup lang="ts">
|
||||
import type { NdmNvrResultVO, NdmRecordCheck, RecordInfo, RecordItem, Station } from '@/apis';
|
||||
import type { NdmNvrResultVO, NdmRecordCheck, RecordItem, Station } from '@/apis';
|
||||
import { getChannelListApi, getRecordCheckApi as getRecordCheckByParentIdApi, reloadAllRecordCheckApi as reloadAllRecordCheckApi, reloadRecordCheckApi as reloadRecordCheckByGbIdApi } from '@/apis';
|
||||
import { exportRecordDiagCsv, transformRecordChecks } from '@/helper';
|
||||
import { useStationStore } from '@/stores';
|
||||
import { downloadByData, formatDuration } from '@/utils';
|
||||
import { useMutation } from '@tanstack/vue-query';
|
||||
import { DownloadOutlined } from '@vicons/antd';
|
||||
import { RefreshOutline } from '@vicons/ionicons5';
|
||||
import dayjs from 'dayjs';
|
||||
import destr from 'destr';
|
||||
import { groupBy } from 'es-toolkit';
|
||||
import { NButton, NCard, NFlex, NIcon, NPagination, NPopconfirm, NPopover, NRadioButton, NRadioGroup, NTooltip, useThemeVars } from 'naive-ui';
|
||||
import { computed, onMounted, ref, toRefs } from 'vue';
|
||||
|
||||
type NvrRecordDiag = {
|
||||
gbCode: string;
|
||||
channelName: string;
|
||||
recordDuration: RecordItem;
|
||||
lostChunks: RecordItem[];
|
||||
};
|
||||
|
||||
// 解析出丢失的录像时间段
|
||||
const transformRecordChecks = (rawRecordChecks: NdmRecordCheck[]): NvrRecordDiag[] => {
|
||||
// 解析diagInfo
|
||||
const parsedRecordChecks = rawRecordChecks.map((recordCheck) => ({
|
||||
...recordCheck,
|
||||
diagInfo: destr<RecordInfo>(recordCheck.diagInfo),
|
||||
}));
|
||||
// 按国标码分组
|
||||
const recordChecksByGbCode = groupBy(parsedRecordChecks, (recordCheck) => recordCheck.gbCode);
|
||||
// 提取分组后的国标码和录像诊断记录
|
||||
const channelGbCodes = Object.keys(recordChecksByGbCode);
|
||||
const recordChecksList = Object.values(recordChecksByGbCode);
|
||||
// 初始化每个通道的录像诊断数据结构
|
||||
const recordDiags = channelGbCodes.map((gbCode, index) => ({
|
||||
gbCode,
|
||||
channelName: recordChecksList.at(index)?.at(-1)?.name ?? '',
|
||||
records: [] as RecordItem[],
|
||||
lostChunks: [] as RecordItem[],
|
||||
}));
|
||||
// 写入同一gbCode的录像片段
|
||||
recordChecksList.forEach((recordChecks, index) => {
|
||||
recordChecks.forEach((recordCheck) => {
|
||||
recordDiags.at(index)?.records.push(...recordCheck.diagInfo.recordList);
|
||||
});
|
||||
});
|
||||
// 过滤掉没有录像记录的通道
|
||||
const filteredRecordDiags = recordDiags.filter((recordDiag) => recordDiag.records.length > 0);
|
||||
// 计算每个通道丢失的录像时间片段
|
||||
filteredRecordDiags.forEach((recordDiag) => {
|
||||
recordDiag.records.forEach((record, index, records) => {
|
||||
if (!!records.at(index + 1)) {
|
||||
// 如果下一段录像的开始时间不等于当前录像的结束时间,则判定为丢失
|
||||
const nextStartTime = records[index + 1].startTime;
|
||||
const currEndTime = record.endTime;
|
||||
if (nextStartTime !== currEndTime) {
|
||||
recordDiag.lostChunks.push({
|
||||
startTime: currEndTime,
|
||||
endTime: nextStartTime,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
return recordDiags.map((recordDiag) => {
|
||||
const firstRecord = recordDiag.records.at(0);
|
||||
const startTime = firstRecord ? dayjs(firstRecord.startTime).format('YYYY-MM-DD HH:mm:ss') : '';
|
||||
const lastRecord = recordDiag.records.at(-1);
|
||||
const endTime = lastRecord ? dayjs(lastRecord.endTime).format('YYYY-MM-DD HH:mm:ss') : '';
|
||||
return {
|
||||
gbCode: recordDiag.gbCode,
|
||||
channelName: recordDiag.channelName,
|
||||
recordDuration: { startTime, endTime },
|
||||
lostChunks: recordDiag.lostChunks,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const props = defineProps<{
|
||||
stationCode: Station['code'];
|
||||
ndmNvr: NdmNvrResultVO;
|
||||
@@ -128,27 +62,9 @@ const { mutate: reloadAllRecordCheck, isPending: reloading } = useMutation({
|
||||
});
|
||||
|
||||
const onExportRecordCheck = () => {
|
||||
const header = '通道名称,开始时间,结束时间,持续时长\n';
|
||||
const rows = recordDiags.value
|
||||
.map((channel) => {
|
||||
if (channel.lostChunks.length === 0) {
|
||||
return `${channel.channelName},,,`;
|
||||
}
|
||||
return channel.lostChunks
|
||||
.map((loss) => {
|
||||
const duration = formatDuration(loss.startTime, loss.endTime);
|
||||
const startTime = dayjs(loss.startTime).format('YYYY-MM-DD HH:mm:ss');
|
||||
const endTime = dayjs(loss.endTime).format('YYYY-MM-DD HH:mm:ss');
|
||||
return `${channel.channelName},${startTime},${endTime},${duration}`;
|
||||
})
|
||||
.join('\n');
|
||||
})
|
||||
.join('\n');
|
||||
const csvContent = header + rows;
|
||||
const stationStore = useStationStore();
|
||||
const stationName = stationStore.stationList.find((station) => station.code === stationCode.value)?.name;
|
||||
const time = dayjs().format('YYYY-MM-DD_HH-mm-ss');
|
||||
downloadByData(csvContent, `${stationName}_录像缺失记录_${time}.csv`, 'text/csv;charset=utf-8', '\ufeff');
|
||||
const stationName = stationStore.stationList.find((station) => station.code === stationCode.value)?.name ?? '';
|
||||
exportRecordDiagCsv(recordDiags.value, stationName);
|
||||
};
|
||||
|
||||
const page = ref(1);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
import type { NdmSwitchPortInfo } from '@/apis';
|
||||
import { getPortStatusVal, transformPortSpeed } from '@/components';
|
||||
import { getPortStatusVal, transformPortSpeed } from '@/helper';
|
||||
import { NCard, NGrid, NGridItem, NPopover } from 'naive-ui';
|
||||
import { computed, toRefs } from 'vue';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { pageDeviceAlarmLogApi, type NdmDeviceAlarmLogResultVO, type NdmDeviceResultVO, type PageParams } from '@/apis';
|
||||
import { renderAlarmDateCell, renderAlarmTypeCell, renderFaultDescriptionCell, renderFaultLevelCell } from '@/components';
|
||||
import { renderAlarmDateCell, renderAlarmTypeCell, renderFaultDescriptionCell, renderFaultLevelCell } from '@/helper';
|
||||
import { useMutation } from '@tanstack/vue-query';
|
||||
import { NCard, NDataTable, type DataTableColumns, type DataTableRowData, type DatePickerProps, type PaginationProps } from 'naive-ui';
|
||||
import { h } from 'vue';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { NdmNvrResultVO } from '@/apis';
|
||||
import { DeviceAlarmHistoryDiagCard, DeviceStatusHistoryDiagCard, DeviceUsageHistoryDiagCard, isNvrCluster, NvrDiskHealthHistoryDiagCard } from '@/components';
|
||||
import { DeviceAlarmHistoryDiagCard, DeviceStatusHistoryDiagCard, DeviceUsageHistoryDiagCard, NvrDiskHealthHistoryDiagCard } from '@/components';
|
||||
import { isNvrCluster } from '@/helper';
|
||||
import dayjs from 'dayjs';
|
||||
import { NButton, NCard, NDatePicker, NFlex, NGi, NGrid, NSelect, type DatePickerProps, type SelectOption } from 'naive-ui';
|
||||
import { computed, onMounted, reactive, ref, toRefs, useTemplateRef } from 'vue';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { pageSnmpLogApi, type NdmSwitchDiagInfo, type NdmSwitchPortInfo, type NdmSwitchResultVO, type PageParams } from '@/apis';
|
||||
import { getPortStatusVal, transformPortSpeed } from '@/components';
|
||||
import { getPortStatusVal, transformPortSpeed } from '@/helper';
|
||||
import { useMutation } from '@tanstack/vue-query';
|
||||
import dayjs from 'dayjs';
|
||||
import destr from 'destr';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { NdmNvrDiagInfo, NdmNvrResultVO } from '@/apis';
|
||||
import { DeviceCommonCard, DeviceHardwareCard, DeviceHeaderCard, isNvrCluster, NvrDiskCard, NvrHistoryDiagCard, NvrRecordDiagCard } from '@/components';
|
||||
import { DeviceCommonCard, DeviceHardwareCard, DeviceHeaderCard, NvrDiskCard, NvrHistoryDiagCard, NvrRecordDiagCard } from '@/components';
|
||||
import { isNvrCluster } from '@/helper';
|
||||
import { useSettingStore } from '@/stores';
|
||||
import { destr } from 'destr';
|
||||
import { NCard, NFlex, NTabPane, NTabs } from 'naive-ui';
|
||||
|
||||
@@ -10,7 +10,7 @@ const deviceTabPanes = Object.keys(DeviceType).map((key) => {
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { LineDevices, NdmDeviceResultVO, NdmNvrResultVO, Station } from '@/apis';
|
||||
import { isNvrCluster } from '@/components';
|
||||
import { isNvrCluster } from '@/helper';
|
||||
import { DeviceType, DeviceTypeName, tryGetDeviceTypeVal, type DeviceTypeKey, type DeviceTypeVal } from '@/enums';
|
||||
import { destr } from 'destr';
|
||||
import {
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
import type { NdmDeviceAlarmLogResultVO, NdmDeviceResultVO, NdmNvrResultVO } from '@/apis';
|
||||
import { AlarmType, DeviceType, DeviceTypeName, FaultLevel, tryGetDeviceTypeVal } from '@/enums';
|
||||
import dayjs from 'dayjs';
|
||||
import { NButton, NPopover, NScrollbar, NTag, type TagProps } from 'naive-ui';
|
||||
import { h } from 'vue';
|
||||
|
||||
export const renderAlarmDateCell = (rowData: NdmDeviceAlarmLogResultVO) => {
|
||||
return dayjs(Number(rowData.alarmDate ?? 0)).format('YYYY-MM-DD HH:mm:ss');
|
||||
};
|
||||
|
||||
export const renderDeviceTypeCell = (rowData: NdmDeviceAlarmLogResultVO) => {
|
||||
const deviceTypeVal = tryGetDeviceTypeVal(rowData.deviceType);
|
||||
if (!deviceTypeVal) return '-';
|
||||
return DeviceTypeName[deviceTypeVal];
|
||||
};
|
||||
|
||||
export const renderAlarmTypeCell = (rowData: NdmDeviceAlarmLogResultVO) => {
|
||||
const { alarmType } = rowData;
|
||||
if (!alarmType) {
|
||||
return '';
|
||||
}
|
||||
return h(NTag, { type: 'default' }, { default: () => AlarmType[alarmType] });
|
||||
};
|
||||
|
||||
export const renderFaultLevelCell = (rowData: NdmDeviceAlarmLogResultVO) => {
|
||||
const { faultLevel } = rowData;
|
||||
if (!faultLevel) {
|
||||
return '';
|
||||
}
|
||||
let type: TagProps['type'] = 'default';
|
||||
if (faultLevel === '1') {
|
||||
type = 'error';
|
||||
} else if (faultLevel === '2') {
|
||||
type = 'warning';
|
||||
} else if (faultLevel === '3') {
|
||||
type = 'info';
|
||||
}
|
||||
return h(NTag, { type }, { default: () => FaultLevel[faultLevel] });
|
||||
};
|
||||
|
||||
export const renderFaultDescriptionCell = (rowData: NdmDeviceAlarmLogResultVO, ndmDevice: NdmDeviceResultVO) => {
|
||||
const isNvrCluster = (ndmDevice: NdmDeviceResultVO) => {
|
||||
const deviceTypeVal = tryGetDeviceTypeVal(ndmDevice.deviceType);
|
||||
if (!deviceTypeVal) return false;
|
||||
const isNvr = deviceTypeVal === DeviceType.Nvr;
|
||||
if (!isNvr) return false;
|
||||
const maybeNvrCluster = ndmDevice as NdmNvrResultVO;
|
||||
return !!maybeNvrCluster.clusterList?.trim() && maybeNvrCluster.clusterList !== maybeNvrCluster.ipAddress;
|
||||
};
|
||||
if (!isNvrCluster(ndmDevice)) {
|
||||
return rowData.faultDescription;
|
||||
}
|
||||
return h(
|
||||
NPopover,
|
||||
{
|
||||
trigger: 'click',
|
||||
},
|
||||
{
|
||||
trigger: () => {
|
||||
return h(
|
||||
NButton,
|
||||
{
|
||||
text: true,
|
||||
type: 'info',
|
||||
},
|
||||
{
|
||||
default: () => '查看',
|
||||
},
|
||||
);
|
||||
},
|
||||
default: () => {
|
||||
return h(
|
||||
NScrollbar,
|
||||
{
|
||||
style: {
|
||||
width: '800px',
|
||||
'max-height': '400px',
|
||||
},
|
||||
},
|
||||
{
|
||||
default: () => {
|
||||
return h('pre', {}, { default: () => rowData.faultDescription?.split('; ').join('\n') ?? '' });
|
||||
},
|
||||
},
|
||||
);
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
export * from './device-alarm';
|
||||
export * from './nvr-cluster';
|
||||
export * from './switch-port';
|
||||
@@ -1,8 +0,0 @@
|
||||
import type { NdmNvrResultVO } from '@/apis';
|
||||
|
||||
export const isNvrCluster = (maybeNvrCluster: NdmNvrResultVO) => {
|
||||
const { ipAddress, clusterList } = maybeNvrCluster;
|
||||
if (!clusterList?.trim()) return false;
|
||||
if (clusterList === ipAddress) return false;
|
||||
return true;
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
import type { NdmSwitchPortInfo } from '@/apis';
|
||||
|
||||
export const getPortStatusVal = (portInfo: NdmSwitchPortInfo): string => {
|
||||
const { upDown } = portInfo;
|
||||
return upDown === 1 ? '启用' : upDown === 2 ? '禁用' : '未知';
|
||||
};
|
||||
|
||||
export const transformPortSpeed = (portInfo: NdmSwitchPortInfo, type: 'in' | 'out' | 'total'): string => {
|
||||
const units = ['b/s', 'Kb/s', 'Mb/s', 'Gb/s', 'Tb/s'];
|
||||
const { inFlow, outFlow, flow } = portInfo;
|
||||
let result: number = 0;
|
||||
if (type === 'in') {
|
||||
result = inFlow;
|
||||
} else if (type === 'out') {
|
||||
result = outFlow;
|
||||
} else if (type === 'total') {
|
||||
result = flow;
|
||||
}
|
||||
let index = 0;
|
||||
while (result >= 1024 && index < units.length - 1) {
|
||||
result /= 1024;
|
||||
index++;
|
||||
}
|
||||
result *= 8;
|
||||
return `${result.toFixed(3)} ${units[index]}`;
|
||||
};
|
||||
@@ -10,12 +10,12 @@ import {
|
||||
type StationAlarmCounts,
|
||||
} from '@/apis';
|
||||
import { AlarmType, DeviceType, DeviceTypeCode, DeviceTypeName, FaultLevel, type DeviceTypeVal } from '@/enums';
|
||||
import { renderAlarmDateCell, renderDeviceTypeCell, renderAlarmTypeCell, renderFaultLevelCell } from '@/helper';
|
||||
import { downloadByData } from '@/utils';
|
||||
import { useMutation } from '@tanstack/vue-query';
|
||||
import dayjs from 'dayjs';
|
||||
import { NButton, NCol, NDataTable, NModal, NRow, NSpace, NStatistic, NTag, type DataTableColumns, type DataTableProps, type DataTableRowData, type PaginationProps } from 'naive-ui';
|
||||
import { computed, h, reactive, ref, toRefs } from 'vue';
|
||||
import { renderAlarmDateCell, renderDeviceTypeCell, renderAlarmTypeCell, renderFaultLevelCell } from '../helper';
|
||||
|
||||
interface Props {
|
||||
station?: Station;
|
||||
|
||||
Reference in New Issue
Block a user