feat: 车站状态页面的交互权限

This commit is contained in:
yangsy
2026-01-13 13:21:50 +08:00
parent 5cc7417981
commit cb015bae30
5 changed files with 222 additions and 129 deletions

View File

@@ -2,4 +2,5 @@ export * from './alarm';
export * from './device';
export * from './permission';
export * from './query';
export * from './station';
export * from './stomp';

View File

@@ -0,0 +1 @@
export * from './use-batch-actions';

View File

@@ -0,0 +1,120 @@
import { usePermission } from '../permission';
import { type Station } from '@/apis';
import { PERMISSION_TYPE_LITERALS, type PermissionType } from '@/enums';
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<Station[]>, abortController?: Ref<AbortController | undefined>) => {
const { hasPermission } = usePermission();
const batchActions = ref<BatchAction[]>([
{
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<Record<Station['code'], boolean>>({});
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<BatchActionKey, () => 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,
};
};