// i18n工具函数 - 用于在 Vue 3 setup 中安全获取 $t import { getCurrentInstance } from 'vue' import zhCN from '../locale/zh-CN.js' import enUS from '../locale/en-US.js' import idID from '../locale/id-ID.js' const MESSAGE_MAP = { 'zh-CN': zhCN, 'en-US': enUS, 'id-ID': idID } const LANGUAGE_STORAGE_KEY = 'language' export function getAppLocale() { try { const lang = uni.getStorageSync(LANGUAGE_STORAGE_KEY) if (lang && MESSAGE_MAP[lang]) return lang } catch (_) {} return 'zh-CN' } function lookupMessage(locale, key) { const segments = String(key).split('.') let node = MESSAGE_MAP[locale] for (const seg of segments) { if (node == null || typeof node !== 'object') return null node = node[seg] } return typeof node === 'string' ? node : null } /** 非 Vue 组件场景下的文案翻译 */ export function translate(key, values) { const locale = getAppLocale() let text = lookupMessage(locale, key) ?? lookupMessage('zh-CN', key) ?? key if (values && typeof values === 'object') { Object.entries(values).forEach(([k, v]) => { text = text.split(`{${k}}`).join(String(v)) }) } return text } /** uni.showModal 封装:默认使用多语言取消/确认按钮 */ export function showModalI18n(options = {}) { const { cancelText, confirmText, showCancel = true, ...rest } = options const modalOptions = { ...rest, showCancel, confirmText: confirmText ?? translate('common.confirm') } if (showCancel !== false) { modalOptions.cancelText = cancelText ?? translate('common.cancel') } return uni.showModal(modalOptions) } /** * 在 setup 中使用 i18n * @returns {{ t: Function, locale: string, i18n: object }} */ export function useI18n() { const instance = getCurrentInstance() if (!instance || !instance.proxy) { return { t: (key) => key, locale: 'en_US', i18n: null } } const proxy = instance.proxy // 返回一个函数,每次调用时动态获取 $t(确保 $t 已经注入) return { t: (key, ...args) => { if (proxy.$t && typeof proxy.$t === 'function') { return proxy.$t(key, ...args) } return key }, locale: proxy.$i18n?.locale || 'en_US', i18n: proxy.$i18n } }