import { defineStore } from 'pinia'; import { i18n, setLanguage, getLanguage, type LanguageCode } from '@src/i18n'; import { SUPPORTED_LANGUAGES, SUPPORTED_LANGUAGE_CODES } from '@src/i18n/constants'; import { resolveSupportedLanguage, detectSystemLanguage } from '@src/i18n/resolver'; // 持久化键 const STORAGE_KEY = 'diona-language'; interface LocaleState { language: LanguageCode; initialized: boolean; } export const useLocaleStore = defineStore('locale', { state: (): LocaleState => ({ language: 'zh', initialized: false, }), getters: { currentLanguage: (state) => state.language, isChinese: (state) => state.language === 'zh', isEnglish: (state) => state.language === 'en', isJapanese: (state) => state.language === 'ja', languageLabel: (state) => { const lang = SUPPORTED_LANGUAGES.find(l => l.code === state.language); return lang?.label || '中文'; }, }, actions: { /** * 初始化语言设置 * 优先级:持久化设置 > 系统语言 > 默认中文 */ async init() { if (this.initialized) return; try { // 1. 尝试从 localStorage 读取持久化设置 const saved = localStorage.getItem(STORAGE_KEY); let lang: LanguageCode = 'zh'; if (saved && SUPPORTED_LANGUAGE_CODES.includes(saved as LanguageCode)) { lang = saved as LanguageCode; } else { // 2. 检测系统语言 lang = detectSystemLanguage(); } // 3. 应用语言设置 await this.setLanguage(lang, false); // 不持久化,因为已经是持久化的值 this.initialized = true; } catch (error) { console.error('Failed to initialize locale store:', error); // 降级处理:使用默认中文 await this.setLanguage('zh', false); this.initialized = true; } }, /** * 设置语言 * @param language 目标语言代码 * @param persist 是否持久化到 localStorage(默认为 true) */ async setLanguage(language: LanguageCode, persist: boolean = true) { // 验证语言代码有效性 const resolvedLang = resolveSupportedLanguage(language); if (resolvedLang === this.language) { return; // 语言未变化 } try { // 1. 更新 i18n 实例 await setLanguage(resolvedLang, i18n); // 2. 更新 store 状态 this.language = resolvedLang; // 3. 持久化到 localStorage if (persist) { localStorage.setItem(STORAGE_KEY, resolvedLang); } // 4. 触发语言变化事件(供其他组件监听) window.dispatchEvent(new CustomEvent('language-changed', { detail: { language: resolvedLang } })); } catch (error) { console.error('Failed to set language:', error); throw error; } }, /** * 切换语言(轮换支持的语言) */ async toggleLanguage() { const currentIndex = SUPPORTED_LANGUAGE_CODES.indexOf(this.language); const nextIndex = (currentIndex + 1) % SUPPORTED_LANGUAGE_CODES.length; const nextLanguage = SUPPORTED_LANGUAGE_CODES[nextIndex]; await this.setLanguage(nextLanguage); }, /** * 重置为系统语言 */ async resetToSystemLanguage() { const systemLang = detectSystemLanguage(); await this.setLanguage(systemLang); }, /** * 同步 i18n 实例与 store 状态(用于外部更改的情况) */ syncWithI18n() { const currentLang = getLanguage(); if (currentLang !== this.language) { this.language = currentLang as LanguageCode; } }, }, }); // 导出类型 export type { LanguageCode };