import { defineStore } from 'pinia'; import type { SiteSettings, FooterSettings, SocialLink, SeoDefaults, NavItem, NavAppearance, ProductSeries, I18nEntry } from '~/types/site'; /** * 官网全局站点状态 * * 在应用启动时一次性拉取全局配置、导航、产品(Mega Menu)与 i18n 词条, * 供 AppHeader / AppFooter 及各页面共享使用。 */ export const useSiteStore = defineStore('site', () => { const { getGlobal, getNav, getI18n, getProducts } = useSiteApi(); const { locale } = useI18n(); // ===== 全局配置 ===== const site = ref(null); const footer = ref(null); const social = ref([]); const seo = ref(null); // ===== 导航 ===== const navItems = ref([]); const navAppearance = ref(null); // ===== 产品(导航 Mega Menu) ===== const productSeries = ref([]); // ===== i18n 词条(dict_key -> entry) ===== const i18nMap = ref>({}); const loaded = ref(false); const loading = ref(false); /** 应用启动时调用,并行拉取全局数据 */ async function init() { if (loaded.value || loading.value) return; loading.value = true; try { const [globalRes, navRes, i18nRes, productsRes] = await Promise.all([ getGlobal(), getNav(), getI18n(), getProducts() ]); if (globalRes) { site.value = globalRes.site; footer.value = globalRes.footer; social.value = globalRes.social ?? []; seo.value = globalRes.seo; } if (navRes) { navItems.value = navRes.items ?? []; navAppearance.value = navRes.appearance; } if (i18nRes) { const map: Record = {}; for (const entry of i18nRes.items ?? []) { map[entry.dict_key] = entry; } i18nMap.value = map; } if (productsRes) { productSeries.value = productsRes.series ?? []; } loaded.value = true; } finally { loading.value = false; } } /** * 翻译 CMS 动态词条(www_i18n_entries) * @param key 词条 key,如 'btn.learn_more' * @param fallback 词条缺失时的回退文案 */ function td(key: string, fallback = ''): string { const entry = i18nMap.value[key]; if (!entry) return fallback || key; const value = locale.value === 'en' ? entry.value_en : entry.value_zh; return value || fallback || key; } /** 根据当前语言取导航入口名称 */ function navLabel(item: NavItem): string { return locale.value === 'en' ? item.name_en : item.name_zh; } return { site, footer, social, seo, navItems, navAppearance, productSeries, i18nMap, loaded, loading, init, td, navLabel }; });