feat: 系统设置面板的交互权限

This commit is contained in:
yangsy
2026-01-13 13:24:44 +08:00
parent a5327427a7
commit bef02fe538
3 changed files with 35 additions and 22 deletions

View File

@@ -3,4 +3,5 @@ export interface Station {
name: string; name: string;
online: boolean; online: boolean;
ip: string; ip: string;
occ?: boolean; // 是否为控制中心
} }

View File

@@ -1,8 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { retentionDaysApi, snapStatusApi, type LineAlarms, type LineDevices, type Station, type VersionInfo } from '@/apis'; import { retentionDaysApi, snapStatusApi, type LineAlarms, type LineDevices, type Station, type VersionInfo } from '@/apis';
import { ThemeSwitch } from '@/components'; import { ThemeSwitch } from '@/components';
import { usePermission } from '@/composables';
import { NDM_ALARM_STORE_ID, NDM_DEVICE_STORE_ID, NDM_STATION_STORE_ID } from '@/constants'; import { NDM_ALARM_STORE_ID, NDM_DEVICE_STORE_ID, NDM_STATION_STORE_ID } from '@/constants';
import { usePollingStore, useSettingStore } from '@/stores'; import { PERMISSION_TYPE_LITERALS } from '@/enums';
import { usePollingStore, useSettingStore, useStationStore } from '@/stores';
import { downloadByData, getAppEnvConfig, parseErrorFeedback, sleep } from '@/utils'; import { downloadByData, getAppEnvConfig, parseErrorFeedback, sleep } from '@/utils';
import { useMutation } from '@tanstack/vue-query'; import { useMutation } from '@tanstack/vue-query';
import { useEventListener } from '@vueuse/core'; import { useEventListener } from '@vueuse/core';
@@ -13,13 +15,20 @@ import localforage from 'localforage';
import { DownloadIcon, Trash2Icon, UploadIcon } from 'lucide-vue-next'; import { DownloadIcon, Trash2Icon, UploadIcon } from 'lucide-vue-next';
import { NButton, NButtonGroup, NDivider, NDrawer, NDrawerContent, NDropdown, NFlex, NFormItem, NIcon, NInput, NInputNumber, NModal, NSwitch, NText, type DropdownOption } from 'naive-ui'; import { NButton, NButtonGroup, NDivider, NDrawer, NDrawerContent, NDropdown, NFlex, NFormItem, NIcon, NInput, NInputNumber, NModal, NSwitch, NText, type DropdownOption } from 'naive-ui';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
const show = defineModel<boolean>('show', { default: false }); const show = defineModel<boolean>('show', { default: false });
const stationStore = useStationStore();
const { stations } = storeToRefs(stationStore);
const occStation = computed(() => stations.value.find((station) => !!station.occ));
const settingsStore = useSettingStore(); const settingsStore = useSettingStore();
const { menuCollpased, stationGridCols, debugModeEnabled, offlineDev } = storeToRefs(settingsStore); const { menuCollpased, stationGridCols, debugModeEnabled, offlineDev } = storeToRefs(settingsStore);
const { hasPermission } = usePermission();
const versionInfo = ref<VersionInfo>({ version: '', buildTime: '' }); const versionInfo = ref<VersionInfo>({ version: '', buildTime: '' });
const { mutate: getVersionInfo } = useMutation({ const { mutate: getVersionInfo } = useMutation({
@@ -303,25 +312,27 @@ const onDrawerAfterLeave = () => {
<NInputNumber v-model:value="stationGridCols" :min="1" :max="10" /> <NInputNumber v-model:value="stationGridCols" :min="1" :max="10" />
</NFormItem> </NFormItem>
<NDivider>告警</NDivider> <template v-if="!!occStation && hasPermission(occStation.code, PERMISSION_TYPE_LITERALS.OPERATION)">
<NFormItem label="告警画面截图保留天数" label-placement="left"> <NDivider>告警</NDivider>
<NFlex justify="space-between" align="center" style="width: 100%"> <NFormItem label="告警画面截图保留天数" label-placement="left">
<NInputNumber v-model:value="retentionDays" :min="1" :max="15" /> <NFlex justify="space-between" align="center" style="width: 100%">
<NButtonGroup> <NInputNumber v-model:value="retentionDays" :min="1" :max="15" />
<NButton secondary size="small" :disabled="retentionDaysSaving" :loading="retentionDaysLoading" @click="() => getRetentionDays()">刷新</NButton> <NButtonGroup>
<NButton secondary size="small" :disabled="retentionDaysLoading" :loading="retentionDaysSaving" @click="() => saveRetentionDays()">保存</NButton> <NButton secondary size="small" :disabled="retentionDaysSaving" :loading="retentionDaysLoading" @click="() => getRetentionDays()">刷新</NButton>
</NButtonGroup> <NButton secondary size="small" :disabled="retentionDaysLoading" :loading="retentionDaysSaving" @click="() => saveRetentionDays()">保存</NButton>
</NFlex> </NButtonGroup>
</NFormItem> </NFlex>
<NFormItem label="自动获取告警画面截图" label-placement="left"> </NFormItem>
<NFlex justify="space-between" align="center" style="width: 100%"> <NFormItem label="自动获取告警画面截图" label-placement="left">
<NSwitch size="small" v-model:value="snapStatus" /> <NFlex justify="space-between" align="center" style="width: 100%">
<NButtonGroup> <NSwitch size="small" v-model:value="snapStatus" />
<NButton secondary size="small" :disabled="snapStatusSaving" :loading="snapStatusLoading" @click="() => getSnapStatus()">刷新</NButton> <NButtonGroup>
<NButton secondary size="small" :disabled="snapStatusLoading" :loading="snapStatusSaving" @click="() => saveSnapStatus()">保存</NButton> <NButton secondary size="small" :disabled="snapStatusSaving" :loading="snapStatusLoading" @click="() => getSnapStatus()">刷新</NButton>
</NButtonGroup> <NButton secondary size="small" :disabled="snapStatusLoading" :loading="snapStatusSaving" @click="() => saveSnapStatus()">保存</NButton>
</NFlex> </NButtonGroup>
</NFormItem> </NFlex>
</NFormItem>
</template>
<template v-if="debugModeEnabled"> <template v-if="debugModeEnabled">
<NDivider title-placement="center">调试</NDivider> <NDivider title-placement="center">调试</NDivider>

View File

@@ -17,12 +17,13 @@ export const useLineStationsMutation = () => {
mutationKey: [LINE_STATIONS_MUTATION_KEY], mutationKey: [LINE_STATIONS_MUTATION_KEY],
mutationFn: async (params: { signal?: AbortSignal }) => { mutationFn: async (params: { signal?: AbortSignal }) => {
const { signal } = params; const { signal } = params;
const { data: ndmStationList } = await axios.get<{ code: string; name: string }[]>(`/minio/ndm/ndm-stations.json?_t=${dayjs().unix()}`, { signal }); const { data: ndmStationList } = await axios.get<Omit<Station, 'online' | 'ip'>[]>(`/minio/ndm/ndm-stations.json?_t=${dayjs().unix()}`, { signal });
const stations = ndmStationList.map<Station>((station) => ({ const stations = ndmStationList.map<Station>((station) => ({
code: station.code ?? '', code: station.code ?? '',
name: station.name ?? '', name: station.name ?? '',
online: false, online: false,
ip: '', ip: '',
occ: station.occ,
})); }));
const verifyList = await batchVerifyApi({ signal }); const verifyList = await batchVerifyApi({ signal });
return stations.map((station) => ({ return stations.map((station) => ({