@liujitcn/kratos-uni-app-core 0.0.49 → 0.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/package.json +1 -1
- package/src/locales/index.ts +21 -5
- package/src/rpc/base/v1/config.ts +12 -0
- package/src/stores/modules/setting.ts +2 -1
package/README.md
CHANGED
|
@@ -69,3 +69,5 @@ import KratosSettingsPage from '@liujitcn/kratos-uni-app-core/components/KratosS
|
|
|
69
69
|
扩展内容由产品模块自行组织完整卡片。页面顺序固定为业务扩展、MFA 与语言、微信设置、退出登录;产品模块可以注册自己的物理页面,并通过后注册的 `SETTINGS` viewKey 覆盖 system 默认包装页。
|
|
70
70
|
|
|
71
71
|
构建与验证命令见 [workspace 文档](../../README.md)。
|
|
72
|
+
|
|
73
|
+
应用配置加载成功后,core 会将 `i18n_customs` 按 `locale + key` 覆盖已注册的本地文案,并刷新页面翻译。仅覆盖已有 key 的非空文案;未配置或已删除的覆盖项恢复本地默认值,未知语言和未知 key 忽略。切换语言时沿用配置重载流程。
|
package/package.json
CHANGED
package/src/locales/index.ts
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* uni-app 国际化运行时:合并 core 和业务模块语言包,并向 Vue 页面、请求工具暴露统一翻译入口。
|
|
3
3
|
* 各语言 JSON 由模块定义文件导入,不能在 JSON 文件内添加注释。
|
|
4
4
|
*/
|
|
5
|
-
import { readonly, ref } from 'vue'
|
|
5
|
+
import { reactive, readonly, ref } from 'vue'
|
|
6
6
|
import type { KratosAppModule } from '../module'
|
|
7
|
+
import type { I18nCustomItem } from '../rpc/base/v1/config'
|
|
7
8
|
import type { OptionLanguageResponse } from '../rpc/base/v1/language'
|
|
8
9
|
import {
|
|
9
10
|
DEFAULT_LOCALE as GENERATED_DEFAULT_LOCALE,
|
|
@@ -30,7 +31,8 @@ export interface LocaleOption {
|
|
|
30
31
|
|
|
31
32
|
const DEFAULT_LOCALE: SupportedLocale = GENERATED_DEFAULT_LOCALE
|
|
32
33
|
const LOCALE_STORAGE_KEY = 'kratos-app:locale'
|
|
33
|
-
const
|
|
34
|
+
const defaultLocaleMessages = new Map<SupportedLocale, LocaleMessages>()
|
|
35
|
+
const localeMessages = reactive(new Map<SupportedLocale, LocaleMessages>())
|
|
34
36
|
const localeChangeHandlers = new Set<() => void | Promise<void>>()
|
|
35
37
|
const mutableLocaleState = ref<SupportedLocale>(DEFAULT_LOCALE)
|
|
36
38
|
const mutableLanguageOptions = ref<LocaleOption[]>([])
|
|
@@ -100,8 +102,8 @@ export function getSupportedLocales(): SupportedLocale[] {
|
|
|
100
102
|
|
|
101
103
|
/** 注册所有模块贡献的语言包并校验语言键集合。 */
|
|
102
104
|
export function registerLocaleMessages(modules: KratosAppModule[]): void {
|
|
103
|
-
|
|
104
|
-
SUPPORTED_LOCALES.forEach((locale) =>
|
|
105
|
+
defaultLocaleMessages.clear()
|
|
106
|
+
SUPPORTED_LOCALES.forEach((locale) => defaultLocaleMessages.set(locale, {}))
|
|
105
107
|
modules.forEach((module) => {
|
|
106
108
|
const expectedKeys = requiredLocaleKeys(module.messages?.[DEFAULT_LOCALE] || {})
|
|
107
109
|
SUPPORTED_LOCALES.forEach((locale) => {
|
|
@@ -111,7 +113,7 @@ export function registerLocaleMessages(modules: KratosAppModule[]): void {
|
|
|
111
113
|
if (keys.join('\u0000') !== expectedKeys.join('\u0000')) {
|
|
112
114
|
throw new Error(`${module.name} 的 ${locale} 语言包键集合不一致`)
|
|
113
115
|
}
|
|
114
|
-
const target =
|
|
116
|
+
const target = defaultLocaleMessages.get(locale) as LocaleMessages
|
|
115
117
|
Object.keys(messages).forEach((key) => {
|
|
116
118
|
if (!isAllowedLocaleKey(module.name, key)) {
|
|
117
119
|
throw new Error(`${module.name} 的语言键命名空间无效: ${key}`)
|
|
@@ -129,6 +131,20 @@ export function registerLocaleMessages(modules: KratosAppModule[]): void {
|
|
|
129
131
|
})
|
|
130
132
|
})
|
|
131
133
|
})
|
|
134
|
+
applyCustomLocaleMessages([])
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** 按语言和已有 key 覆盖本地文案,每次重新应用以清除已删除的自定义配置。 */
|
|
138
|
+
export function applyCustomLocaleMessages(customs: I18nCustomItem[]): void {
|
|
139
|
+
SUPPORTED_LOCALES.forEach((locale) => {
|
|
140
|
+
const messages = { ...(defaultLocaleMessages.get(locale) ?? {}) }
|
|
141
|
+
customs.forEach((item) => {
|
|
142
|
+
if (parseSupportedLocale(item.locale) !== locale || !item.key || !item.value) return
|
|
143
|
+
if (!Object.prototype.hasOwnProperty.call(messages, item.key)) return
|
|
144
|
+
messages[item.key] = item.value
|
|
145
|
+
})
|
|
146
|
+
localeMessages.set(locale, messages)
|
|
147
|
+
})
|
|
132
148
|
}
|
|
133
149
|
|
|
134
150
|
/** 校验公共键和当前业务模块专属的语言键命名空间。 */
|
|
@@ -40,6 +40,18 @@ export interface GetConfigResponse {
|
|
|
40
40
|
configs: ConfigItem[];
|
|
41
41
|
/** AI 助手是否可用 */
|
|
42
42
|
ai_enabled: boolean;
|
|
43
|
+
/** 全部语言的自定义国际化覆盖项 */
|
|
44
|
+
i18n_customs: I18nCustomItem[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** 全部语言的自定义国际化覆盖项。 */
|
|
48
|
+
export interface I18nCustomItem {
|
|
49
|
+
/** 语言区域 */
|
|
50
|
+
locale: string;
|
|
51
|
+
/** 国际化语言键 */
|
|
52
|
+
key: string;
|
|
53
|
+
/** 自定义翻译内容 */
|
|
54
|
+
value: string;
|
|
43
55
|
}
|
|
44
56
|
|
|
45
57
|
/** Base系统配置公共服务 */
|
|
@@ -2,7 +2,7 @@ import { defConfigService } from '../../api/base/v1/config'
|
|
|
2
2
|
import { defineStore } from 'pinia'
|
|
3
3
|
import { ref } from 'vue'
|
|
4
4
|
import { BaseConfigSite } from '../../rpc/base/v1/config'
|
|
5
|
-
import { t } from '../../locales'
|
|
5
|
+
import { applyCustomLocaleMessages, t } from '../../locales'
|
|
6
6
|
|
|
7
7
|
const REQUIRED_APP_CONFIGS = [
|
|
8
8
|
{ key: 'serviceProtocol', nameKey: 'core.protocol.service' },
|
|
@@ -36,6 +36,7 @@ export const useSettingStore = defineStore('setting', () => {
|
|
|
36
36
|
aiEnabled.value = false
|
|
37
37
|
return
|
|
38
38
|
}
|
|
39
|
+
applyCustomLocaleMessages(res.i18n_customs ?? [])
|
|
39
40
|
const nextData = new Map<string, string>()
|
|
40
41
|
res.configs.forEach((item) => {
|
|
41
42
|
nextData.set(item.key, item.value)
|