From 86775a6eb2e6e86e40f07f1143581b4160aad96a Mon Sep 17 00:00:00 2001 From: yangsy Date: Thu, 15 Jan 2026 14:22:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E8=BD=A6=E7=AB=99?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=93=8D=E4=BD=9C?= =?UTF-8?q?=E6=A0=8F=E4=BA=A4=E4=BA=92=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/composables/index.ts | 1 + src/composables/station/index.ts | 1 + src/composables/station/use-batch-actions.ts | 104 +++++++++ src/pages/station/station-page.vue | 223 ++++++++----------- 4 files changed, 205 insertions(+), 124 deletions(-) create mode 100644 src/composables/station/index.ts create mode 100644 src/composables/station/use-batch-actions.ts diff --git a/src/composables/index.ts b/src/composables/index.ts index 0e70e34..4694032 100644 --- a/src/composables/index.ts +++ b/src/composables/index.ts @@ -1,4 +1,5 @@ export * from './alarm'; export * from './device'; export * from './query'; +export * from './station'; export * from './stomp'; diff --git a/src/composables/station/index.ts b/src/composables/station/index.ts new file mode 100644 index 0000000..d8cdbb3 --- /dev/null +++ b/src/composables/station/index.ts @@ -0,0 +1 @@ +export * from './use-batch-actions'; diff --git a/src/composables/station/use-batch-actions.ts b/src/composables/station/use-batch-actions.ts new file mode 100644 index 0000000..9628c7d --- /dev/null +++ b/src/composables/station/use-batch-actions.ts @@ -0,0 +1,104 @@ +import { type Station } from '@/apis'; +import { computed, ref, watch, type Ref } from 'vue'; + +type BatchActionKey = 'export-icmp' | 'export-record' | 'sync-camera' | 'sync-nvr'; + +type BatchAction = { + label: string; + key: BatchActionKey; + active: boolean; +}; + +export const useBatchActions = (stations: Ref, abortController?: Ref) => { + const batchActions = ref([ + { + label: '导出设备状态', + key: 'export-icmp', + active: false, + }, + { + label: '导出录像诊断', + key: 'export-record', + active: false, + }, + { + label: '同步摄像机', + key: 'sync-camera', + active: false, + }, + { + label: '同步录像机通道', + key: 'sync-nvr', + active: false, + }, + ]); + + const selectedAction = computed(() => { + return batchActions.value.find((action) => action.active); + }); + + const selectableStations = computed(() => { + if (!selectedAction.value) return []; + return stations.value; + }); + + const stationSelection = ref>({}); + + const toggleSelectAction = (action: BatchAction) => { + batchActions.value.forEach((batchAction) => { + if (batchAction.key === action.key) { + if (batchAction.active) stationSelection.value = {}; + batchAction.active = !batchAction.active; + } else { + batchAction.active = false; + } + }); + }; + + const toggleSelectAllStations = (checked: boolean) => { + if (!checked) { + stationSelection.value = {}; + return; + } + selectableStations.value.forEach((station) => { + stationSelection.value[station.code] = checked; + }); + }; + + watch(selectedAction, () => { + toggleSelectAllStations(false); + }); + + const confirmAction = (callbacks: Record void>) => { + const { key } = selectedAction.value ?? {}; + if (!key) return; + const noStationSeleted = !Object.values(stationSelection.value).some((selected) => selected); + if (noStationSeleted) { + window.$message.warning('请选择车站'); + return; + } + callbacks[key](); + }; + + const cancelAction = () => { + abortController?.value?.abort(); + stationSelection.value = {}; + batchActions.value.forEach((batchAction) => { + batchAction.active = false; + }); + }; + + return { + batchActions, + selectedAction, + + selectableStations, + stationSelection, + + toggleSelectAction, + toggleSelectAllStations, + + confirmAction, + cancelAction, + }; +}; diff --git a/src/pages/station/station-page.vue b/src/pages/station/station-page.vue index a609e7a..6c32537 100644 --- a/src/pages/station/station-page.vue +++ b/src/pages/station/station-page.vue @@ -1,177 +1,148 @@