feat: 添加批量导出录像诊断并优化导出体验
This commit is contained in:
@@ -48,3 +48,13 @@ export const reloadAllRecordCheckApi = async (dayOffset: number, options?: { sta
|
|||||||
if (!data) throw new Error(`${data}`);
|
if (!data) throw new Error(`${data}`);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const batchExportRecordCheckApi = async (params: { checkDuration: number; gapSeconds: number; stationCode: Station['code'][] }, options?: { signal?: AbortSignal }) => {
|
||||||
|
const { signal } = options ?? {};
|
||||||
|
const { checkDuration, gapSeconds, stationCode } = params;
|
||||||
|
const client = userClient;
|
||||||
|
const endpoint = `/api/ndm/ndmRecordCheck/batchExportByTemplate`;
|
||||||
|
const resp = await client.post<Blob>(endpoint, { checkDuration, gapSeconds, stationCode }, { responseType: 'blob', retRaw: true, signal });
|
||||||
|
const data = unwrapResponse(resp);
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getRecordCheckApi, type NdmNvrResultVO, type Station } from '@/apis';
|
import { batchExportRecordCheckApi, getRecordCheckApi, pageDefParameterApi, type NdmNvrResultVO, type Station } from '@/apis';
|
||||||
import { exportRecordDiagCsv, isNvrCluster, transformRecordChecks } from '@/helpers';
|
import { exportRecordDiagCsv, isNvrCluster, transformRecordChecks } from '@/helpers';
|
||||||
import { useDeviceStore } from '@/stores';
|
import { useDeviceStore } from '@/stores';
|
||||||
import { parseErrorFeedback } from '@/utils';
|
import { downloadByData, parseErrorFeedback } from '@/utils';
|
||||||
import { useMutation } from '@tanstack/vue-query';
|
import { useMutation } from '@tanstack/vue-query';
|
||||||
import { isCancel } from 'axios';
|
import { isCancel } from 'axios';
|
||||||
import { NButton, NGrid, NGridItem, NModal, NScrollbar, NSpin } from 'naive-ui';
|
import dayjs from 'dayjs';
|
||||||
|
import { NButton, NFlex, NGrid, NGridItem, NModal, NScrollbar, NSpin } from 'naive-ui';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { computed, ref, toRefs } from 'vue';
|
import { computed, ref, toRefs } from 'vue';
|
||||||
|
|
||||||
@@ -60,7 +61,10 @@ const { mutate: exportRecordDiags, isPending: exporting } = useMutation({
|
|||||||
return checks;
|
return checks;
|
||||||
},
|
},
|
||||||
onSuccess: (checks, { stationCode }) => {
|
onSuccess: (checks, { stationCode }) => {
|
||||||
if (!checks || checks.length === 0) return;
|
if (!checks || checks.length === 0) {
|
||||||
|
window.$message.info(`没有录像诊断数据`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
const recordDiags = transformRecordChecks(checks);
|
const recordDiags = transformRecordChecks(checks);
|
||||||
exportRecordDiagCsv(recordDiags, nvrClusterRecord.value[stationCode]?.stationName ?? '');
|
exportRecordDiagCsv(recordDiags, nvrClusterRecord.value[stationCode]?.stationName ?? '');
|
||||||
},
|
},
|
||||||
@@ -72,7 +76,48 @@ const { mutate: exportRecordDiags, isPending: exporting } = useMutation({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const { mutate: batchExportRecordCheck, isPending: batchExporting } = useMutation({
|
||||||
|
mutationFn: async () => {
|
||||||
|
const { records = [] } = await pageDefParameterApi({
|
||||||
|
model: {
|
||||||
|
key: 'NVR_GAP_SECONDS',
|
||||||
|
},
|
||||||
|
extra: {},
|
||||||
|
current: 1,
|
||||||
|
size: 1,
|
||||||
|
sort: 'id',
|
||||||
|
order: 'descending',
|
||||||
|
});
|
||||||
|
const gapSeconds = parseInt(records.at(0)?.value ?? '5');
|
||||||
|
|
||||||
|
window.$message.info('导出耗时较长,请耐心等待...');
|
||||||
|
|
||||||
|
const data = await batchExportRecordCheckApi(
|
||||||
|
{
|
||||||
|
checkDuration: 90,
|
||||||
|
gapSeconds,
|
||||||
|
stationCode: stations.value.map((station) => station.code),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
signal: abortController.value.signal,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
onSuccess: (data) => {
|
||||||
|
const time = dayjs().format('YYYY-MM-DD_HH-mm-ss');
|
||||||
|
downloadByData(data, `录像缺失记录_${time}.xlsx`);
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
if (isCancel(error)) return;
|
||||||
|
console.error(error);
|
||||||
|
const errorFeedback = parseErrorFeedback(error);
|
||||||
|
window.$message.error(errorFeedback);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const onAfterLeave = () => {
|
const onAfterLeave = () => {
|
||||||
|
abortController.value.abort();
|
||||||
emit('afterLeave');
|
emit('afterLeave');
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@@ -92,6 +137,11 @@ const onAfterLeave = () => {
|
|||||||
</NSpin>
|
</NSpin>
|
||||||
</NScrollbar>
|
</NScrollbar>
|
||||||
</template>
|
</template>
|
||||||
|
<template #action>
|
||||||
|
<NFlex justify="flex-end" align="center">
|
||||||
|
<NButton secondary :loading="batchExporting" @click="() => batchExportRecordCheck()">导出全部</NButton>
|
||||||
|
</NFlex>
|
||||||
|
</template>
|
||||||
</NModal>
|
</NModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ const { mutate: syncCamera, isPending: cameraSyncing } = useMutation({
|
|||||||
window.$notification.info({
|
window.$notification.info({
|
||||||
title: '摄像机同步结果',
|
title: '摄像机同步结果',
|
||||||
content: notices.join(','),
|
content: notices.join(','),
|
||||||
duration: 3000,
|
duration: 10000,
|
||||||
});
|
});
|
||||||
if (successRequests.length > 0) {
|
if (successRequests.length > 0) {
|
||||||
// 摄像机同步后,需要重新查询一次设备
|
// 摄像机同步后,需要重新查询一次设备
|
||||||
@@ -123,7 +123,7 @@ const { mutate: syncNvrChannels, isPending: nvrChannelsSyncing } = useMutation({
|
|||||||
window.$notification.info({
|
window.$notification.info({
|
||||||
title: '录像机通道同步结果',
|
title: '录像机通道同步结果',
|
||||||
content: notices.join(','),
|
content: notices.join(','),
|
||||||
duration: 3000,
|
duration: 10000,
|
||||||
});
|
});
|
||||||
cancelAction();
|
cancelAction();
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user