import { defineStore } from 'pinia' import { ref, watch } from 'vue' const DARK_KEY = 'oci-portal:dark' const LOGO_KEY = 'oci-portal:logo' /** logo 款式:burst 星爆(现款)/ seal 波浪封印 */ export type LogoVariant = 'burst' | 'seal' function initialDark(): boolean { const saved = localStorage.getItem(DARK_KEY) if (saved !== null) return saved === '1' return window.matchMedia('(prefers-color-scheme: dark)').matches } function initialLogo(): LogoVariant { return localStorage.getItem(LOGO_KEY) === 'seal' ? 'seal' : 'burst' } /** 跨页面共享的界面状态:侧栏收缩、明暗主题 */ export const useAppStore = defineStore('app', () => { const sidebarCollapsed = ref(false) /** 暗色主题:默认跟随系统,手动切换后按选择记忆 */ const dark = ref(initialDark()) // html.dark 驱动 main.css 的变量覆盖,Naive 主题在 App.vue 跟随 watch( dark, (v) => { document.documentElement.classList.toggle('dark', v) localStorage.setItem(DARK_KEY, v ? '1' : '0') }, { immediate: true }, ) /** logo 款式:默认星爆,设置 · 关于点击 logo 切换后按选择记忆 */ const logoVariant = ref(initialLogo()) watch(logoVariant, (v) => localStorage.setItem(LOGO_KEY, v)) function toggleSidebar() { sidebarCollapsed.value = !sidebarCollapsed.value } function toggleDark() { dark.value = !dark.value } function toggleLogoVariant() { logoVariant.value = logoVariant.value === 'burst' ? 'seal' : 'burst' } return { sidebarCollapsed, toggleSidebar, dark, toggleDark, logoVariant, toggleLogoVariant } })