@liujitcn/kratos-uni-app-core 0.0.49 → 0.0.50

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 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
@@ -7,7 +7,7 @@
7
7
  "type": "git",
8
8
  "url": "git@github.com:liujitcn/kratos-admin.git"
9
9
  },
10
- "version": "0.0.49",
10
+ "version": "0.0.50",
11
11
  "type": "module",
12
12
  "files": [
13
13
  "dist",
@@ -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 localeMessages = new Map<SupportedLocale, LocaleMessages>()
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
- localeMessages.clear()
104
- SUPPORTED_LOCALES.forEach((locale) => localeMessages.set(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 = localeMessages.get(locale) as LocaleMessages
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)