import { usePermission } from '../permission'; import { type Station } from '@/apis'; import { PERMISSION_TYPE_LITERALS, type PermissionType } from '@/enums'; import { objectEntries } from '@vueuse/core'; import type { CheckboxProps } from 'naive-ui'; import { computed, ref, watch, type Ref } from 'vue'; type BatchActionKey = 'export-icmp' | 'export-record' | 'sync-camera' | 'sync-nvr'; type BatchAction = { label: string; key: BatchActionKey; permission: PermissionType; active: boolean; }; export const useBatchActions = (stations: Ref, abortController?: Ref) => { const { hasPermission } = usePermission(); const batchActions = ref([ { label: '导出设备状态', key: 'export-icmp', permission: PERMISSION_TYPE_LITERALS.VIEW, active: false, }, { label: '导出录像诊断', key: 'export-record', permission: PERMISSION_TYPE_LITERALS.VIEW, active: false, }, { label: '同步摄像机', key: 'sync-camera', permission: PERMISSION_TYPE_LITERALS.OPERATION, active: false, }, { label: '同步录像机通道', key: 'sync-nvr', permission: PERMISSION_TYPE_LITERALS.OPERATION, active: false, }, ]); const selectedAction = computed(() => { return batchActions.value.find((action) => action.active); }); const selectableStations = computed(() => { if (!selectedAction.value) return []; const result: Station[] = []; if (selectedAction.value.permission === PERMISSION_TYPE_LITERALS.VIEW) { result.push(...stations.value.filter((station) => hasPermission(station.code, PERMISSION_TYPE_LITERALS.VIEW))); } if (selectedAction.value.permission === PERMISSION_TYPE_LITERALS.OPERATION) { result.push(...stations.value.filter((station) => hasPermission(station.code, PERMISSION_TYPE_LITERALS.OPERATION))); } return result; }); const stationSelection = ref>({}); const selectionProps = computed(() => { const selectableStationsLength = selectableStations.value.length; const selectedStationsLength = objectEntries(stationSelection.value).filter(([, selected]) => selected).length; const disabled = selectableStationsLength === 0; const checked = selectableStationsLength > 0 && selectedStationsLength === selectableStationsLength; const indeterminate = selectableStationsLength > 0 && selectedStationsLength > 0 && selectedStationsLength < selectableStationsLength; return { disabled, checked, indeterminate, }; }); 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, selectionProps, toggleSelectAction, toggleSelectAllStations, confirmAction, cancelAction, }; };