Files
ndm-web-client/src/components/global/settings-drawer.vue
2025-11-20 10:58:19 +08:00

112 lines
4.1 KiB
Vue

<script setup lang="ts">
import type { VersionInfo } from '@/apis';
import { ThemeSwitch } from '@/components';
import { STATION_LIST_QUERY_KEY } from '@/constants';
import { useDebugModeStore, useLayoutStore, useQueryControlStore } from '@/stores';
import { getAppEnvConfig } from '@/utils';
import { useQueryClient } from '@tanstack/vue-query';
import { useEventListener } from '@vueuse/core';
import axios from 'axios';
import { NButton, NDivider, NDrawer, NDrawerContent, NFlex, NFormItem, NInput, NInputNumber, NModal, NRadio, NRadioGroup, NText } from 'naive-ui';
import { storeToRefs } from 'pinia';
import { onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const show = defineModel<boolean>('show');
const layoutStore = useLayoutStore();
const { stationGridColumns } = storeToRefs(layoutStore);
const queryControlStore = useQueryControlStore();
const { stationVerifyMode } = storeToRefs(queryControlStore);
const queryClient = useQueryClient();
watch(stationVerifyMode, () => {
queryClient.cancelQueries({ queryKey: [STATION_LIST_QUERY_KEY] });
queryClient.invalidateQueries({ queryKey: [STATION_LIST_QUERY_KEY] });
queryClient.refetchQueries({ queryKey: [STATION_LIST_QUERY_KEY] });
});
const versionInfo = ref<VersionInfo>({ version: '', buildTime: '' });
onMounted(async () => {
const { data } = await axios.get<VersionInfo>(`/manifest.json?t=${Date.now()}`);
versionInfo.value = data;
});
const debugModeStore = useDebugModeStore();
const { debugEnabled } = storeToRefs(debugModeStore);
const debugCodeModalShow = ref(false);
const debugCode = ref('');
const enableDebug = () => {
const { debugCode: expectedDebugCode } = getAppEnvConfig();
if (debugCode.value !== expectedDebugCode) {
window.$message.error('调试授权码错误');
return;
}
debugCodeModalShow.value = false;
debugCode.value = '';
debugModeStore.enableDebug();
};
const disableDebug = () => {
debugCodeModalShow.value = false;
debugModeStore.disableDebug();
};
useEventListener('keydown', (event) => {
const { ctrlKey, altKey, code } = event;
if (ctrlKey && altKey && code === 'KeyD') {
debugCodeModalShow.value = true;
}
});
</script>
<template>
<NDrawer v-model:show="show" :width="330">
<NDrawerContent closable title="系统设置" :native-scrollbar="false">
<NFlex vertical>
<NDivider>主题</NDivider>
<NFormItem label="深色模式" label-placement="left">
<ThemeSwitch />
</NFormItem>
<template v-if="route.path === '/station'">
<NDivider>布局</NDivider>
<NFormItem label="车站列数" label-placement="left">
<NInputNumber v-model:value="stationGridColumns" :min="1" :max="10" />
</NFormItem>
</template>
<template v-if="debugEnabled">
<NDivider>调试</NDivider>
<NFormItem label="车站Ping模式" label-placement="left">
<NRadioGroup v-model:value="stationVerifyMode">
<NRadio value="concurrent">并发Ping</NRadio>
<NRadio value="batch">接口Ping</NRadio>
</NRadioGroup>
</NFormItem>
</template>
</NFlex>
<template #footer>
<NFlex vertical justify="flex-end" align="center" style="width: 100%; font-size: 12px; gap: 4px">
<NText :depth="3">平台版本: {{ versionInfo.version }} ({{ versionInfo.buildTime }})</NText>
</NFlex>
</template>
</NDrawerContent>
</NDrawer>
<NModal v-model:show="debugCodeModalShow" preset="dialog" type="info">
<template #header>
<NText v-if="!debugEnabled">请输入调试授权码</NText>
<NText v-else>确认关闭调试模式</NText>
</template>
<NInput v-if="!debugEnabled" v-model:value="debugCode" placeholder="输入授权码" />
<template #action>
<NButton @click="debugCodeModalShow = false">取消</NButton>
<NButton v-if="!debugEnabled" type="primary" @click="enableDebug">启用</NButton>
<NButton v-else type="primary" @click="disableDebug">确认</NButton>
</template>
</NModal>
</template>
<style scoped lang="scss"></style>