refactor: move /helper

This commit is contained in:
yangsy
2025-11-27 16:01:50 +08:00
parent d4eade65c4
commit f278a690c6
15 changed files with 110 additions and 96 deletions

View File

@@ -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);

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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 {

View File

@@ -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;

View File

@@ -0,0 +1,26 @@
import type { Station } from '@/apis';
import type { NvrRecordDiag } from './record-check';
import { downloadByData, formatDuration } from '@/utils';
import dayjs from 'dayjs';
export const exportRecordDiagCsv = (recordDiags: NvrRecordDiag[], stationName: Station['name']) => {
const header = '通道名称,开始时间,结束时间,持续时长\n';
const rows = recordDiags
.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 time = dayjs().format('YYYY-MM-DD_HH-mm-ss');
downloadByData(csvContent, `${stationName}_录像缺失记录_${time}.csv`, 'text/csv;charset=utf-8', '\ufeff');
};

View File

@@ -1,3 +1,5 @@
export * from './device-alarm';
export * from './export-record-diag-csv';
export * from './nvr-cluster';
export * from './record-check';
export * from './switch-port';

View File

@@ -0,0 +1,68 @@
import type { NdmRecordCheck, RecordInfo, RecordItem } from '@/apis';
import dayjs from 'dayjs';
import { destr } from 'destr';
import { groupBy } from 'es-toolkit';
export type NvrRecordDiag = {
gbCode: string;
channelName: string;
recordDuration: RecordItem;
lostChunks: RecordItem[];
};
// 解析出丢失的录像时间段
export 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,
};
});
};

View File

@@ -9,7 +9,7 @@ import {
removeCameraIgnoreApi,
type NdmDeviceAlarmLogResultVO,
} from '@/apis';
import { renderAlarmDateCell, renderAlarmTypeCell, renderDeviceTypeCell, renderFaultLevelCell } from '@/components';
import { renderAlarmDateCell, renderAlarmTypeCell, renderDeviceTypeCell, renderFaultLevelCell } from '@/helper';
import { AlarmType, DeviceType, DeviceTypeCode, DeviceTypeName, FaultLevel, tryGetDeviceTypeVal, type DeviceTypeVal } from '@/enums';
import { useAlarmStore, useStationStore } from '@/stores';
import { downloadByData } from '@/utils';