feat: multiselect stations to export device icmp state

This commit is contained in:
yangsy
2025-12-03 10:44:14 +08:00
parent e19fcf79a6
commit a215f2e391
2 changed files with 37 additions and 32 deletions

View File

@@ -1,13 +1,17 @@
<script setup lang="ts">
import { exportIcmpApi } from '@/apis';
import { exportIcmpApi, type Station } from '@/apis';
import { DeviceType } from '@/enums';
import { useDeviceStore, useStationStore } from '@/stores';
import { useDeviceStore } from '@/stores';
import { downloadByData } from '@/utils';
import { useMutation } from '@tanstack/vue-query';
import dayjs from 'dayjs';
import { NButton, NFlex, NGrid, NGridItem, NModal, NRadio, NRadioGroup, NStatistic } from 'naive-ui';
import { storeToRefs } from 'pinia';
import { computed, ref } from 'vue';
import { computed, ref, toRefs } from 'vue';
const props = defineProps<{
stationList: Station[];
}>();
const show = defineModel<boolean>('show', { default: false });
@@ -15,11 +19,11 @@ const emit = defineEmits<{
'after-leave': [];
}>();
const stationStore = useStationStore();
const { stationList } = storeToRefs(stationStore);
const deviceStore = useDeviceStore();
const { lineDevices } = storeToRefs(deviceStore);
const { stationList } = toRefs(props);
const status = ref('');
const onAfterLeave = () => {

View File

@@ -3,7 +3,6 @@ import { syncCameraApi, syncNvrChannelsApi, type Station } from '@/apis';
import { DeviceAlarmDetailModal, DeviceExportModal, DeviceParamsConfigModal, OfflineDeviceDetailModal, RecordCheckExportModal, StationCard } from '@/components';
import { useLineAlarmsQuery, useLineDevicesQuery } from '@/composables';
import { useAlarmStore, useDeviceStore, usePollingStore, useSettingStore, useStationStore } from '@/stores';
import { sleep } from '@/utils';
import { useMutation } from '@tanstack/vue-query';
import { NGrid, NGi, NScrollbar, NFlex, NButtonGroup, NButton, NCheckbox } from 'naive-ui';
import { storeToRefs } from 'pinia';
@@ -38,9 +37,9 @@ const selectedAction = ref<Action>(null);
const showOperation = ref(false);
const stationSelectable = ref(false);
const stationSelection = ref<Record<Station['code'], boolean>>({});
// TODO: 后期导出设备也会支持选择车站而不是目前的Modal交互
const showIcmpExportModal = ref(false);
const showRecordCheckExportModal = ref(false);
const onToggleSelectAll = (checked: boolean) => {
if (!checked) {
stationSelection.value = {};
@@ -48,23 +47,23 @@ const onToggleSelectAll = (checked: boolean) => {
stationSelection.value = Object.fromEntries(stationList.value.map((station) => [station.code, true]));
}
};
const onAction = (action: Action) => {
selectedAction.value = action;
if (action === 'export-icmp') {
showIcmpExportModal.value = true;
} else if (action === 'export-record') {
showOperation.value = true;
stationSelectable.value = true;
} else if (action === 'sync-camera') {
showOperation.value = true;
stationSelectable.value = true;
} else if (action === 'sync-nvr') {
showOperation.value = true;
stationSelectable.value = true;
} else {
return;
}
if (action === null) return;
showOperation.value = true;
stationSelectable.value = true;
};
const onCancel = () => {
selectedAction.value = null;
showOperation.value = false;
stationSelectable.value = false;
stationSelection.value = {};
};
const onFinish = onCancel;
const { mutate: syncCamera, isPending: cameraSyncing } = useMutation({
mutationFn: async () => {
const stationCodes = Object.entries(stationSelection.value)
@@ -101,6 +100,7 @@ const { mutate: syncCamera, isPending: cameraSyncing } = useMutation({
onCancel();
},
});
const { mutate: syncNvrChannels, isPending: nvrChannelsSyncing } = useMutation({
mutationFn: async () => {
const stationCodes = Object.entries(stationSelection.value)
@@ -133,23 +133,31 @@ const { mutate: syncNvrChannels, isPending: nvrChannelsSyncing } = useMutation({
onCancel();
},
});
const confirming = computed(() => cameraSyncing.value || nvrChannelsSyncing.value);
const onConfirm = async () => {
const noStationSelected = !Object.values(stationSelection.value).some((selected) => selected);
if (selectedAction.value === 'export-icmp') {
if (noStationSelected) {
window.$message.warning('请选择要导出设备状态的车站');
return;
}
showIcmpExportModal.value = true;
} else if (selectedAction.value === 'export-record') {
if (!Object.values(stationSelection.value).some((selected) => selected)) {
if (noStationSelected) {
window.$message.warning('请选择要导出录像诊断的车站');
return;
}
showRecordCheckExportModal.value = true;
} else if (selectedAction.value === 'sync-camera') {
if (!Object.values(stationSelection.value).some((selected) => selected)) {
if (noStationSelected) {
window.$message.warning('请选择要同步摄像机的车站');
return;
}
syncCamera();
} else if (selectedAction.value === 'sync-nvr') {
if (!Object.values(stationSelection.value).some((selected) => selected)) {
if (noStationSelected) {
window.$message.warning('请选择要同步录像机通道的车站');
return;
}
@@ -158,13 +166,6 @@ const onConfirm = async () => {
return;
}
};
const onCancel = () => {
selectedAction.value = null;
showOperation.value = false;
stationSelectable.value = false;
stationSelection.value = {};
};
const onFinish = onCancel;
// 车站卡片的事件
const selectedStation = ref<Station>();
@@ -225,7 +226,7 @@ const openDeviceParamsConfigModal = (station: Station) => {
<!-- 设备配置面板对话框 -->
<DeviceParamsConfigModal v-model:show="showDeviceParamsConfigModal" :station="selectedStation" />
<!-- 设备状态导出对话框 -->
<DeviceExportModal v-model:show="showIcmpExportModal" @after-leave="onFinish" />
<DeviceExportModal v-model:show="showIcmpExportModal" :station-list="stationList.filter((station) => stationSelection[station.code])" @after-leave="onFinish" />
<!-- 录像诊断导出对话框 -->
<RecordCheckExportModal v-model:show="showRecordCheckExportModal" :stations="stationList.filter((station) => stationSelection[station.code])" @after-leave="onFinish" />
</template>