import { defineStore } from 'pinia' import { getConfig } from '@/api/app' import configs from '@/config' interface AppSate { config: Record /** 是否已尝试过拉取 getConfig(失败也置 true,避免路由守卫死循环) */ configFetchAttempted: boolean isMobile: boolean isCollapsed: boolean isRouteShow: boolean } const useAppStore = defineStore({ id: 'app', state: (): AppSate => { return { config: {}, configFetchAttempted: false, isMobile: true, isCollapsed: false, isRouteShow: true } }, actions: { getImageUrl(url: string) { if (!url || typeof url !== 'string') return '' if (url.startsWith('http://') || url.startsWith('https://')) return url const path = url.startsWith('/') ? url : '/' + url const oss = String(this.config.oss_domain || '').replace(/\/$/, '') if (oss) { return `${oss}${path}` } // 开发环境:后台接口与 Vite 不同端口时,相对路径不能拼到 location.origin(应对接到 php 静态域名) const apiRoot = String(configs.baseUrl || '/').replace(/\/+$/, '') if (apiRoot.startsWith('http://') || apiRoot.startsWith('https://')) { try { return new URL(path, `${apiRoot}/`).href } catch { return `${apiRoot}${path}` } } const origin = typeof window !== 'undefined' ? window.location.origin : '' return origin ? `${origin}${path}` : path }, getConfig() { return new Promise((resolve, reject) => { getConfig() .then((data) => { this.config = data resolve(data) }) .catch((err) => { reject(err) }) }) }, setMobile(value: boolean) { this.isMobile = value }, toggleCollapsed(toggle?: boolean) { this.isCollapsed = toggle ?? !this.isCollapsed }, refreshView() { this.isRouteShow = false nextTick(() => { this.isRouteShow = true }) } } }) export default useAppStore