chore
This commit is contained in:
22
src/components/theme-switch.vue
Normal file
22
src/components/theme-switch.vue
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { useThemeStore } from '@/stores/theme';
|
||||||
|
import { MoonOutline, SunnyOutline } from '@vicons/ionicons5';
|
||||||
|
import { NIcon, NSwitch } from 'naive-ui';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
|
||||||
|
const themeStore = useThemeStore();
|
||||||
|
const { darkThemeEnabled } = storeToRefs(themeStore);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NSwitch v-model:value="darkThemeEnabled" size="small">
|
||||||
|
<template #unchecked-icon>
|
||||||
|
<NIcon :component="SunnyOutline" />
|
||||||
|
</template>
|
||||||
|
<template #checked-icon>
|
||||||
|
<NIcon :component="MoonOutline" />
|
||||||
|
</template>
|
||||||
|
</NSwitch>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
119
src/layouts/app-layout.vue
Normal file
119
src/layouts/app-layout.vue
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
function renderIcon(icon: Component): () => VNode {
|
||||||
|
return () => h(NIcon, null, { default: () => h(icon) });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ChevronDown } from '@vicons/ionicons5';
|
||||||
|
import { AlertFilled, AreaChartOutlined, FileTextFilled, HomeFilled, LogoutOutlined, VideoCameraFilled } from '@vicons/antd';
|
||||||
|
import { NButton, NDropdown, NFlex, NIcon, NLayout, NLayoutContent, NLayoutFooter, NLayoutHeader, NLayoutSider, NMenu, NScrollbar, type DropdownOption, type MenuOption } from 'naive-ui';
|
||||||
|
import { h, ref, type Component, type VNode } from 'vue';
|
||||||
|
import { RouterLink, useRoute, useRouter } from 'vue-router';
|
||||||
|
import { useStationListQuery } from '@/composables/query/use-station-list-query';
|
||||||
|
import ThemeSwitch from '@/components/theme-switch.vue';
|
||||||
|
import { useUserStore } from '@/stores/user';
|
||||||
|
|
||||||
|
useStationListQuery();
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const menuOptions = ref<MenuOption[]>([
|
||||||
|
{
|
||||||
|
label: () => h(RouterLink, { to: '/dashboard' }, { default: () => '今日数据看板' }),
|
||||||
|
key: '/dashboard',
|
||||||
|
icon: renderIcon(HomeFilled),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: () => h(RouterLink, { to: '/device' }, { default: () => '实时设备状态' }),
|
||||||
|
key: '/device',
|
||||||
|
icon: renderIcon(VideoCameraFilled),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: () => h(RouterLink, { to: '/alarm' }, { default: () => '设备告警记录' }),
|
||||||
|
key: '/alarm',
|
||||||
|
icon: renderIcon(AlertFilled),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: () => h(RouterLink, { to: '/statistics' }, { default: () => '设备性能统计' }),
|
||||||
|
key: '/statistics',
|
||||||
|
icon: renderIcon(AreaChartOutlined),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: () => h(RouterLink, { to: '/log' }, { default: () => '系统日志记录' }),
|
||||||
|
key: '/log',
|
||||||
|
icon: renderIcon(FileTextFilled),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const dropdownOptions = ref<DropdownOption[]>([
|
||||||
|
{
|
||||||
|
label: '退出登录',
|
||||||
|
key: 'logout',
|
||||||
|
icon: renderIcon(LogoutOutlined),
|
||||||
|
onClick: async () => {
|
||||||
|
const userStore = useUserStore();
|
||||||
|
await userStore.userLogout();
|
||||||
|
router.push('/login');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const selectDropdownOption = (key: string, option: DropdownOption) => {
|
||||||
|
if (typeof option['onClick'] === 'function') {
|
||||||
|
option['onClick']();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<NScrollbar x-scrollable style="width: 100vw; height: 100vh">
|
||||||
|
<NLayout has-sider :content-style="{ 'min-width': '1400px' }">
|
||||||
|
<NLayoutSider bordered collapsed :collapse-mode="'width'" :collapsed-width="60">
|
||||||
|
<NMenu collapsed :collapsed-width="60" :collapsed-icon-size="18" :value="route.path" :options="menuOptions" />
|
||||||
|
</NLayoutSider>
|
||||||
|
<NLayout :native-scrollbar="false">
|
||||||
|
<NLayoutHeader bordered class="app-layout-header">
|
||||||
|
<NFlex justify="space-between" align="center" :size="8" style="width: 100%; height: 100%">
|
||||||
|
<span style="font-size: 16px; font-weight: 500; margin-left: 16px">网络设备管理平台</span>
|
||||||
|
<NFlex align="center" :size="8">
|
||||||
|
<ThemeSwitch />
|
||||||
|
<NDropdown trigger="hover" show-arrow :options="dropdownOptions" @select="selectDropdownOption">
|
||||||
|
<NButton secondary icon-placement="right" style="margin-right: 8px">
|
||||||
|
<template #default>
|
||||||
|
<span>你好</span>
|
||||||
|
</template>
|
||||||
|
<template #icon>
|
||||||
|
<NIcon :component="ChevronDown" />
|
||||||
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</NDropdown>
|
||||||
|
</NFlex>
|
||||||
|
</NFlex>
|
||||||
|
</NLayoutHeader>
|
||||||
|
<NLayoutContent class="app-layout-content" :native-scrollbar="false" :content-style="{ padding: '8px' }">
|
||||||
|
<RouterView />
|
||||||
|
</NLayoutContent>
|
||||||
|
<NLayoutFooter bordered class="app-layout-footer" />
|
||||||
|
</NLayout>
|
||||||
|
</NLayout>
|
||||||
|
</NScrollbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
$layout-header-height: 48px;
|
||||||
|
$layout-footer-height: 48px;
|
||||||
|
|
||||||
|
.app-layout-header {
|
||||||
|
height: $layout-header-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-layout-content {
|
||||||
|
height: calc(100vh - $layout-header-height - $layout-footer-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-layout-footer {
|
||||||
|
height: $layout-footer-height;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user