20260917212907

This commit is contained in:
oneao committed 2026-09-17 21:29:08 +08:00
1 parent 6fa3d8535e
commit 5cbf745bbf
115 files changed
+4104 -85

No files matched your search

+61
View File
@@ -1,6 +1,22 @@
import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
import { loadDataApi } from '@/services/api'
import { BUILTIN_MESSAGES } from '@/i18n/builtin-messages'
/** SQL 字符串字面量转义(b_locale 来自 s_i18n_type,仍按不可信输入处理) */
function sqlQuote(value) {
return `N'${String(value).replace(/'/g, "''")}'`
}
// 已加载的语言译文缓存:locale -> { key: value }(只存库表译文,内置兜底在合并时再加)
const messageCache = new Map()
// 同一语言的并发请求复用同一个 Promise,避免切换语言瞬间打出一串相同请求
const pendingMessages = new Map()
function clearMessageCache() {
messageCache.clear()
pendingMessages.clear()
}
// UI 翻译运行时与业务语言清单共用一个入口。
const localeRef = ref('zh-CN')
@@ -24,6 +40,7 @@ export function setMessages(messages, locale = undefined) {
export function clearMessages() {
messagesRef.value = {}
clearMessageCache()
}
export const useI18nStore = defineStore('i18n', () => {
@@ -78,6 +95,49 @@ export const useI18nStore = defineStore('i18n', () => {
return loadLanguages(true)
}
/* ---------- 译文(s_i18n) ---------- */
// 把某份语言的译文写进运行时;库表译文覆盖前端内置兜底文案
function applyMessages(locale) {
// 异步请求回来时语言可能又被切走了,只认当前语言,避免串台
if (String(localeRef.value) !== String(locale)) return
setMessages({ ...BUILTIN_MESSAGES[locale], ...messageCache.get(locale) }, locale)
}
/**
* 加载指定语言的译文;不传则取当前语言。
* 已加载过直接复用缓存(无请求),并发复用同一个 Promise,失败不抛出(界面回落内置/兜底文案)。
*/
async function loadMessages(locale = localeRef.value, force = false) {
const target = String(locale || '').trim()
if (!target) return {}
if (!force && messageCache.has(target)) {
applyMessages(target)
return messageCache.get(target)
}
if (pendingMessages.has(target)) return pendingMessages.get(target)
const task = loadDataApi('s_i18n', `b_canuse = 1 and b_locale = ${sqlQuote(target)}`, 'b_key ASC')
.then((res) => {
const map = {}
for (const row of res.data || []) {
if (row.b_key) map[String(row.b_key)] = row.b_value == null ? '' : String(row.b_value)
}
messageCache.set(target, map)
applyMessages(target)
return map
})
.catch((e) => {
error.value = e?.message || String(e)
return {}
})
.finally(() => {
pendingMessages.delete(target)
})
pendingMessages.set(target, task)
return task
}
function toggleLocale() {
setLocale(localeRef.value === 'zh-CN' ? 'en-US' : 'zh-CN')
}
@@ -98,6 +158,7 @@ export const useI18nStore = defineStore('i18n', () => {
clearMessages,
toggleLocale,
loadLanguages,
loadMessages,
refresh,
}
}, {