@liujitcn/kratos-admin-core 0.0.19 → 0.0.21

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.
Files changed (110) hide show
  1. package/README.md +2 -2
  2. package/dist/package/declarations/src/api/base/language.d.ts +8 -0
  3. package/dist/package/declarations/src/components/Dialog/ProDialog.vue.d.ts +1 -0
  4. package/dist/package/declarations/src/components/LocaleSwitch/index.vue.d.ts +3 -0
  5. package/dist/package/declarations/src/index.d.ts +2 -0
  6. package/dist/package/declarations/src/locales/index.d.ts +63 -0
  7. package/dist/package/declarations/src/modules/index.d.ts +7 -2
  8. package/dist/package/declarations/src/request.d.ts +1 -0
  9. package/dist/package/declarations/src/routers/modules/staticRouter.d.ts +1 -0
  10. package/dist/package/declarations/src/rpc/base/v1/config.d.ts +2 -0
  11. package/dist/package/declarations/src/rpc/base/v1/language.d.ts +26 -0
  12. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +79 -0
  13. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +102 -0
  14. package/dist/package/declarations/src/stores/interface/index.d.ts +2 -0
  15. package/dist/package/declarations/src/stores/runtime.d.ts +1 -0
  16. package/dist/package/declarations/src/utils/dict.d.ts +2 -2
  17. package/dist/package/declarations/src/utils/index.d.ts +1 -1
  18. package/dist/package/declarations/src/utils/oauthProvider.d.ts +2 -0
  19. package/dist/package/declarations/src/utils/passwordStrength.d.ts +0 -7
  20. package/dist/package/src/App.vue +10 -1
  21. package/dist/package/src/api/base/language.ts +20 -0
  22. package/dist/package/src/api/base/oauth.ts +0 -1
  23. package/dist/package/src/api/system/auth.ts +0 -1
  24. package/dist/package/src/bootstrap.ts +57 -2
  25. package/dist/package/src/components/CronExpression/index.vue +80 -82
  26. package/dist/package/src/components/Dialog/FormDialog.vue +9 -4
  27. package/dist/package/src/components/Dialog/ProDialog.vue +10 -4
  28. package/dist/package/src/components/Dict/index.vue +5 -2
  29. package/dist/package/src/components/ECharts/config/index.ts +6 -1
  30. package/dist/package/src/components/ErrorMessage/index.vue +3 -1
  31. package/dist/package/src/components/ImportExcel/index.vue +29 -18
  32. package/dist/package/src/components/LocaleSwitch/index.vue +28 -0
  33. package/dist/package/src/components/PasswordStrength/index.vue +8 -5
  34. package/dist/package/src/components/ProForm/components/DynamicList.vue +8 -3
  35. package/dist/package/src/components/ProForm/components/KvList.vue +14 -6
  36. package/dist/package/src/components/ProTable/components/ColSetting.vue +7 -5
  37. package/dist/package/src/components/ProTable/components/TableColumn.vue +2 -1
  38. package/dist/package/src/components/ProTable/index.vue +36 -11
  39. package/dist/package/src/components/SearchForm/components/SearchFormItem.vue +9 -4
  40. package/dist/package/src/components/SearchForm/index.vue +6 -3
  41. package/dist/package/src/components/SelectFilter/index.vue +4 -1
  42. package/dist/package/src/components/SelectIcon/index.vue +8 -4
  43. package/dist/package/src/components/TreeFilter/index.vue +14 -6
  44. package/dist/package/src/components/Upload/File.vue +18 -13
  45. package/dist/package/src/components/Upload/Files.vue +22 -15
  46. package/dist/package/src/components/Upload/Img.vue +14 -11
  47. package/dist/package/src/components/Upload/Imgs.vue +15 -12
  48. package/dist/package/src/components/WangEditor/index.vue +12 -4
  49. package/dist/package/src/directives/modules/copy.ts +2 -1
  50. package/dist/package/src/hooks/useDownload.ts +3 -2
  51. package/dist/package/src/hooks/useHandleData.ts +5 -4
  52. package/dist/package/src/hooks/useTheme.ts +2 -1
  53. package/dist/package/src/hooks/useTime.ts +11 -2
  54. package/dist/package/src/index.ts +2 -0
  55. package/dist/package/src/layouts/components/Header/ToolBarRight.vue +2 -0
  56. package/dist/package/src/layouts/components/Header/components/AssemblySize.vue +8 -6
  57. package/dist/package/src/layouts/components/Header/components/Avatar.vue +11 -9
  58. package/dist/package/src/layouts/components/Header/components/Breadcrumb.vue +10 -2
  59. package/dist/package/src/layouts/components/Header/components/Fullscreen.vue +4 -2
  60. package/dist/package/src/layouts/components/Header/components/InfoDialog.vue +6 -3
  61. package/dist/package/src/layouts/components/Header/components/PasswordDialog.vue +6 -3
  62. package/dist/package/src/layouts/components/Header/components/SearchMenu.vue +5 -3
  63. package/dist/package/src/layouts/components/Header/components/ThemeSetting.vue +3 -1
  64. package/dist/package/src/layouts/components/Tabs/components/MoreButton.vue +9 -7
  65. package/dist/package/src/layouts/components/ThemeDrawer/index.vue +27 -24
  66. package/dist/package/src/locales/README.md +15 -0
  67. package/dist/package/src/locales/en-US.json +258 -0
  68. package/dist/package/src/locales/es-ES.json +258 -0
  69. package/dist/package/src/locales/fr-FR.json +258 -0
  70. package/dist/package/src/locales/index.ts +223 -0
  71. package/dist/package/src/locales/ja-JP.json +258 -0
  72. package/dist/package/src/locales/ko-KR.json +258 -0
  73. package/dist/package/src/locales/zh-CN.json +258 -0
  74. package/dist/package/src/locales/zh-TW.json +258 -0
  75. package/dist/package/src/modules/index.ts +7 -2
  76. package/dist/package/src/modules/kratosAdmin.ts +19 -1
  77. package/dist/package/src/request.ts +8 -1
  78. package/dist/package/src/routers/index.ts +4 -1
  79. package/dist/package/src/routers/modules/dynamicRouter.ts +3 -2
  80. package/dist/package/src/routers/modules/staticRouter.ts +8 -4
  81. package/dist/package/src/rpc/base/v1/config.ts +2 -0
  82. package/dist/package/src/rpc/base/v1/language.ts +37 -0
  83. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +81 -0
  84. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +117 -0
  85. package/dist/package/src/stores/interface/index.ts +2 -0
  86. package/dist/package/src/stores/modules/config.ts +5 -1
  87. package/dist/package/src/stores/modules/user.ts +2 -1
  88. package/dist/package/src/stores/runtime.ts +1 -0
  89. package/dist/package/src/utils/color.ts +5 -4
  90. package/dist/package/src/utils/dict.ts +27 -4
  91. package/dist/package/src/utils/eleValidate.ts +3 -2
  92. package/dist/package/src/utils/errorHandler.ts +9 -8
  93. package/dist/package/src/utils/index.ts +7 -6
  94. package/dist/package/src/utils/oauthProvider.ts +15 -10
  95. package/dist/package/src/utils/passwordCrypto.ts +3 -2
  96. package/dist/package/src/utils/passwordStrength.ts +1 -16
  97. package/dist/package/src/utils/request.ts +13 -8
  98. package/dist/package/src/views/error/403.vue +3 -1
  99. package/dist/package/src/views/error/404.vue +3 -1
  100. package/dist/package/src/views/error/500.vue +3 -1
  101. package/dist/package/src/views/error/pending.vue +5 -2
  102. package/dist/package/src/views/login/components/LoginForm.vue +53 -27
  103. package/dist/package/src/views/login/index.scss +6 -0
  104. package/dist/package/src/views/login/index.vue +2 -0
  105. package/dist/package/types/generated/auto-imports.d.ts +129 -111
  106. package/dist/package/types/generated/components.d.ts +67 -67
  107. package/package.json +3 -1
  108. package/types/generated/auto-imports.d.ts +129 -111
  109. package/types/generated/components.d.ts +67 -67
  110. package/vite.config.ts +8 -0
package/README.md CHANGED
@@ -142,8 +142,8 @@ core 通过 `ADMIN_STATIC_VIEWS` 注册全部默认静态页面,后注册业
142
142
 
143
143
  ## 公共 Interface
144
144
 
145
- | 能力 | 入口 |
146
- | ---------------- | ------------------------------------------------------ |
145
+ | 能力 | 入口 |
146
+ | ---------------- | ----------------------------------------------------------- |
147
147
  | 应用与模块注册 | `@liujitcn/kratos-admin-core` |
148
148
  | 请求客户端 | `@liujitcn/kratos-admin-core/request` |
149
149
  | 路由与跳转 | `@liujitcn/kratos-admin-core/navigation` |
@@ -0,0 +1,8 @@
1
+ import type { GetLanguageRequest, GetLanguageResponse, LanguageService } from "../../rpc/base/v1/language";
2
+ /** 语言公共服务。 */
3
+ export declare class LanguageServiceImpl implements LanguageService {
4
+ /** 查询当前支持的语言和主语言。 */
5
+ GetLanguage(request: GetLanguageRequest): Promise<GetLanguageResponse>;
6
+ }
7
+ /** 主语言公共服务。 */
8
+ export declare const defLanguageService: LanguageServiceImpl;
@@ -1,3 +1,4 @@
1
+ /** 通用弹窗组件属性。 */
1
2
  interface ProDialogProps {
2
3
  modelValue: boolean;
3
4
  title?: string;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -1,3 +1,5 @@
1
1
  export * from "./modules";
2
+ export * from "./locales";
3
+ export { defLanguageService } from "./api/base/language";
2
4
  export { kratosAdminModule } from "./modules/kratosAdmin";
3
5
  export { bootstrapAdminApp } from "./bootstrap";
@@ -0,0 +1,63 @@
1
+ import "dayjs/locale/en";
2
+ import "dayjs/locale/ja";
3
+ import "dayjs/locale/zh-cn";
4
+ import "dayjs/locale/zh-tw";
5
+ import "dayjs/locale/ko";
6
+ import "dayjs/locale/fr";
7
+ import "dayjs/locale/es";
8
+ import type { AdminModule } from "../modules";
9
+ import type { GetLanguageResponse } from "../rpc/base/v1/language";
10
+ /** 管理端支持的语言区域。 */
11
+ export declare const SUPPORTED_LOCALES: readonly ["zh-CN", "zh-TW", "en-US", "ja-JP", "ko-KR", "fr-FR", "es-ES"];
12
+ /** 管理端支持的语言区域类型。 */
13
+ export type SupportedLocale = (typeof SUPPORTED_LOCALES)[number];
14
+ /** 单个模块的扁平语言包。 */
15
+ export type LocaleMessages = Record<string, string>;
16
+ /** 翻译插值参数。 */
17
+ export type LocaleParams = Record<string, string | number>;
18
+ /** 运行时语言选项。 */
19
+ export interface LocaleOption {
20
+ /** 标准语言代码。 */
21
+ language_code: SupportedLocale;
22
+ /** 语言名称。 */
23
+ language_name: string;
24
+ /** 本地语言名称。 */
25
+ native_name: string;
26
+ /** 排序值。 */
27
+ sort: number;
28
+ }
29
+ export declare const DEFAULT_LOCALE: SupportedLocale;
30
+ export declare const LOCALE_STORAGE_KEY = "kratos-admin:locale";
31
+ /** 管理端 Vue I18n 实例。 */
32
+ export declare const adminI18n: import("vue-i18n").I18n<{}, {}, {}, "zh-CN", false>;
33
+ /** 规范化任意语言输入到管理端白名单。 */
34
+ export declare function normalizeLocale(value?: string): SupportedLocale;
35
+ /** 注册模块语言包并校验七语键、占位符和命名空间。 */
36
+ export declare function registerLocaleMessages(modules: AdminModule[]): void;
37
+ /** 初始化持久化语言偏好并同步日期库。 */
38
+ export declare function initializeLocale(): SupportedLocale;
39
+ /** 应用后端语言配置,并在当前语言不可用时回退到接口主语言。 */
40
+ export declare function applyLanguageConfig(response: GetLanguageResponse): void;
41
+ /** 获取当前接口配置的语言选项。 */
42
+ export declare function getLanguageOptions(): LocaleOption[];
43
+ /** 获取当前可切换的语言区域。 */
44
+ export declare function getSupportedLocales(): SupportedLocale[];
45
+ /** 获取当前规范语言区域。 */
46
+ export declare function getCurrentLocale(): SupportedLocale;
47
+ /** 获取非 Axios 请求统一使用的语言头。 */
48
+ export declare function getLocaleRequestHeaders(): Record<"Accept-Language", SupportedLocale>;
49
+ /** 切换语言并刷新动态本地化数据。 */
50
+ export declare function setCurrentLocale(value: SupportedLocale): Promise<void>;
51
+ /** 注册语言切换后的动态数据刷新处理器。 */
52
+ export declare function registerLocaleChangeHandler(handler: () => void | Promise<void>): () => void;
53
+ /** 在非组件代码中翻译稳定语言键。 */
54
+ export declare function t(key: string, params?: LocaleParams): string;
55
+ /** 管理端响应式语言状态。 */
56
+ export declare function useLocaleStore(): {
57
+ locale: Readonly<globalThis.Ref<"zh-CN" | "zh-TW" | "en-US" | "ja-JP" | "ko-KR" | "fr-FR" | "es-ES", "zh-CN" | "zh-TW" | "en-US" | "ja-JP" | "ko-KR" | "fr-FR" | "es-ES">>;
58
+ localeIndex: globalThis.ComputedRef<number>;
59
+ languageOptions: globalThis.ComputedRef<LocaleOption[]>;
60
+ supportedLocales: globalThis.ComputedRef<("zh-CN" | "zh-TW" | "en-US" | "ja-JP" | "ko-KR" | "fr-FR" | "es-ES")[]>;
61
+ setLocale: typeof setCurrentLocale;
62
+ t: typeof t;
63
+ };
@@ -1,5 +1,6 @@
1
1
  import type { Component } from "vue";
2
2
  import type { RouteLocationNormalizedLoaded } from "vue-router";
3
+ import type { LocaleMessages, SupportedLocale } from "../locales";
3
4
  /**
4
5
  * 管理端视图加载器。
5
6
  */
@@ -35,8 +36,10 @@ export interface AdminHeaderTool {
35
36
  export interface AdminUserMenuAction {
36
37
  /** 操作唯一名称。 */
37
38
  name: string;
38
- /** 操作显示名称。 */
39
- label: string;
39
+ /** 操作显示名称对应的稳定语言键。 */
40
+ labelKey?: string;
41
+ /** 兼容未迁移模块的静态显示名称。 */
42
+ label?: string;
40
43
  /** 对应后端动态菜单名称,菜单不存在时不显示操作。 */
41
44
  menuName: string;
42
45
  /** 操作图标。 */
@@ -65,6 +68,8 @@ export interface AdminModule {
65
68
  routeOptions?: Record<string, AdminRouteOptions>;
66
69
  /** 模块提供的命名扩展,由扩展所属业务包定义具体类型。 */
67
70
  extensions?: Record<string, unknown>;
71
+ /** 模块按语言区域贡献的扁平语言包。 */
72
+ messages?: Partial<Record<SupportedLocale, LocaleMessages>>;
68
73
  }
69
74
  /**
70
75
  * 声明一个可被管理端宿主注册的模块。
@@ -1,2 +1,3 @@
1
1
  export { default } from "./utils/request";
2
2
  export { ensureAccessToken, getRequestAccessToken, handleAuthExpired, hasValidAccessToken, requestBaseURL } from "./utils/request";
3
+ export { getLocaleRequestHeaders } from "./locales";
@@ -14,6 +14,7 @@ export declare const errorRouter: ({
14
14
  }>;
15
15
  meta: {
16
16
  title: string;
17
+ titleKey: string;
17
18
  };
18
19
  } | {
19
20
  path: string;
@@ -6,6 +6,8 @@ export interface GetConfigRequest {
6
6
  }
7
7
  /** 系统配置项 */
8
8
  export interface ConfigItem {
9
+ /** 配置ID */
10
+ id: number;
9
11
  /** 配置key */
10
12
  key: string;
11
13
  /** 配置value */
@@ -0,0 +1,26 @@
1
+ /** 查询语言请求参数。 */
2
+ export interface GetLanguageRequest {
3
+ }
4
+ /** 支持的语言。 */
5
+ export interface LanguageItem {
6
+ /** 标准语言代码 */
7
+ language_code: string;
8
+ /** 语言名称 */
9
+ language_name: string;
10
+ /** 本地语言名称 */
11
+ native_name: string;
12
+ /** 排序,值越小越靠前 */
13
+ sort: number;
14
+ }
15
+ /** 当前支持的语言查询结果。 */
16
+ export interface GetLanguageResponse {
17
+ /** 当前支持的语言列表 */
18
+ languages: LanguageItem[];
19
+ /** 主语言代码 */
20
+ primary_language_code: string;
21
+ }
22
+ /** 语言公共服务。 */
23
+ export interface LanguageService {
24
+ /** 查询当前支持的语言和主语言。 */
25
+ GetLanguage(request: GetLanguageRequest): Promise<GetLanguageResponse>;
26
+ }
@@ -1,5 +1,6 @@
1
1
  import type { Status } from "../../../common/v1/enum";
2
2
  import type { Empty } from "../../../google/protobuf/empty";
3
+ import type { TranslationStatus } from "./base_translation";
3
4
  /** 字典选项查询条件 */
4
5
  export interface OptionBaseDictRequest {
5
6
  }
@@ -79,6 +80,8 @@ export interface BaseDictForm {
79
80
  code: string;
80
81
  /** 字典名称 */
81
82
  name: string;
83
+ /** 非主语言翻译 */
84
+ translations: BaseDictTranslation[];
82
85
  /** 状态 */
83
86
  status: Status;
84
87
  }
@@ -101,6 +104,8 @@ export interface BaseDictItemForm {
101
104
  tag_type: string;
102
105
  /** 排序 */
103
106
  sort: number;
107
+ /** 非主语言翻译 */
108
+ translations: BaseDictItemTranslation[];
104
109
  /** 状态 */
105
110
  status: Status;
106
111
  }
@@ -156,6 +161,8 @@ export interface BaseDict {
156
161
  code: string;
157
162
  /** 字典名称 */
158
163
  name: string;
164
+ /** 非主语言翻译 */
165
+ translations: BaseDictTranslation[];
159
166
  /** 状态 */
160
167
  status: Status;
161
168
  /** 创建时间 */
@@ -177,6 +184,8 @@ export interface BaseDictItem {
177
184
  tag_type: string;
178
185
  /** 排序 */
179
186
  sort: number;
187
+ /** 非主语言翻译 */
188
+ translations: BaseDictItemTranslation[];
180
189
  /** 状态 */
181
190
  status: Status;
182
191
  /** 创建时间 */
@@ -184,6 +193,76 @@ export interface BaseDictItem {
184
193
  /** 更新时间 */
185
194
  updated_at: string;
186
195
  }
196
+ /** 字典翻译 */
197
+ export interface BaseDictTranslation {
198
+ /** 主键ID */
199
+ id: number;
200
+ /** 字典ID */
201
+ dict_id: number;
202
+ /** 语言代码 */
203
+ locale: string;
204
+ /** 字典名称 */
205
+ name: string;
206
+ /** 翻译状态 */
207
+ translation_status: TranslationStatus;
208
+ /** 中文源文SHA-256 */
209
+ source_hash: string;
210
+ /** 机器翻译提供方 */
211
+ translation_provider: string;
212
+ /** 最近机器翻译时间 */
213
+ translated_at: string;
214
+ /** 审核人ID */
215
+ reviewed_by: number;
216
+ /** 审核时间 */
217
+ reviewed_at: string;
218
+ /** 创建人ID */
219
+ created_by: number;
220
+ /** 更新人ID */
221
+ updated_by: number;
222
+ /** 创建时间 */
223
+ created_at: string;
224
+ /** 更新时间 */
225
+ updated_at: string;
226
+ /** 删除时间 */
227
+ deleted_at: number;
228
+ /** 中文源文是否已变化 */
229
+ source_changed: boolean;
230
+ }
231
+ /** 字典项翻译 */
232
+ export interface BaseDictItemTranslation {
233
+ /** 主键ID */
234
+ id: number;
235
+ /** 字典项ID */
236
+ dict_item_id: number;
237
+ /** 语言代码 */
238
+ locale: string;
239
+ /** 字典项标签 */
240
+ label: string;
241
+ /** 翻译状态 */
242
+ translation_status: TranslationStatus;
243
+ /** 中文源文SHA-256 */
244
+ source_hash: string;
245
+ /** 机器翻译提供方 */
246
+ translation_provider: string;
247
+ /** 最近机器翻译时间 */
248
+ translated_at: string;
249
+ /** 审核人ID */
250
+ reviewed_by: number;
251
+ /** 审核时间 */
252
+ reviewed_at: string;
253
+ /** 创建人ID */
254
+ created_by: number;
255
+ /** 更新人ID */
256
+ updated_by: number;
257
+ /** 创建时间 */
258
+ created_at: string;
259
+ /** 更新时间 */
260
+ updated_at: string;
261
+ /** 删除时间 */
262
+ deleted_at: number;
263
+ /** 中文源文是否已变化 */
264
+ source_changed: boolean;
265
+ }
187
266
  /** Admin字典服务 */
188
267
  export interface BaseDictService {
189
268
  /** 查询字典列表 */
@@ -0,0 +1,102 @@
1
+ /** 翻译状态 */
2
+ export declare enum TranslationStatus {
3
+ TRANSLATION_STATUS_UNSPECIFIED = 0,
4
+ TRANSLATION_STATUS_PENDING = 1,
5
+ TRANSLATION_STATUS_MACHINE = 2,
6
+ TRANSLATION_STATUS_REVIEWED = 3
7
+ }
8
+ /** 翻译资源类型 */
9
+ export declare enum TranslationResourceType {
10
+ TRANSLATION_RESOURCE_TYPE_UNSPECIFIED = 0,
11
+ TRANSLATION_RESOURCE_TYPE_MENU = 1,
12
+ TRANSLATION_RESOURCE_TYPE_DICT = 2,
13
+ TRANSLATION_RESOURCE_TYPE_DICT_ITEM = 3,
14
+ TRANSLATION_RESOURCE_TYPE_CONFIG = 4
15
+ }
16
+ /** 系统配置翻译字段 */
17
+ export declare enum BaseConfigTranslationField {
18
+ BASE_CONFIG_TRANSLATION_FIELD_UNSPECIFIED = 0,
19
+ BASE_CONFIG_TRANSLATION_FIELD_NAME = 1,
20
+ BASE_CONFIG_TRANSLATION_FIELD_VALUE = 2
21
+ }
22
+ /** 生成翻译草稿请求 */
23
+ export interface GenerateTranslationDraftRequest {
24
+ /** 资源类型 */
25
+ resource_type: TranslationResourceType;
26
+ /** 已保存资源ID */
27
+ resource_id: number;
28
+ /** 目标语言代码 */
29
+ target_locale: string;
30
+ /** 系统配置翻译字段,配置资源必填 */
31
+ field: BaseConfigTranslationField;
32
+ }
33
+ /** 生成翻译草稿响应 */
34
+ export interface GenerateTranslationDraftResponse {
35
+ /** 资源类型 */
36
+ resource_type: TranslationResourceType;
37
+ /** 资源ID */
38
+ resource_id: number;
39
+ /** 语言区域 */
40
+ locale: string;
41
+ /** 机器翻译草稿 */
42
+ translation: string;
43
+ /** 翻译状态 */
44
+ translation_status: TranslationStatus;
45
+ /** 中文源文SHA-256 */
46
+ source_hash: string;
47
+ /** 机器翻译提供方 */
48
+ translation_provider: string;
49
+ /** 最近机器翻译时间 */
50
+ translated_at: string;
51
+ /** 系统配置翻译字段 */
52
+ field: BaseConfigTranslationField;
53
+ }
54
+ /** 系统配置单语言翻译 */
55
+ export interface BaseConfigTranslation {
56
+ /** 翻译记录ID */
57
+ id: number;
58
+ /** 系统配置ID */
59
+ config_id: number;
60
+ /** 语言区域 */
61
+ locale: string;
62
+ /** 翻译字段:name或value */
63
+ field: BaseConfigTranslationField;
64
+ /** 翻译文本 */
65
+ text: string;
66
+ /** 翻译审核状态 */
67
+ translation_status: TranslationStatus;
68
+ /** 中文源文SHA-256 */
69
+ source_hash: string;
70
+ /** 中文源文是否已变化 */
71
+ source_changed: boolean;
72
+ /** 机器翻译提供方 */
73
+ translation_provider: string;
74
+ /** 最近机器翻译时间 */
75
+ translated_at: string;
76
+ /** 审核人ID */
77
+ reviewed_by: number;
78
+ /** 审核时间 */
79
+ reviewed_at: string;
80
+ /** 创建人ID */
81
+ created_by: number;
82
+ /** 更新人ID */
83
+ updated_by: number;
84
+ /** 创建时间 */
85
+ created_at: string;
86
+ /** 更新时间 */
87
+ updated_at: string;
88
+ /** 删除时间 */
89
+ deleted_at: number;
90
+ }
91
+ /** 代码生成单语言国际化配置 */
92
+ export interface CodeGenLocaleConfig {
93
+ /** 业务或字段描述 */
94
+ comment: string;
95
+ /** 左树描述 */
96
+ left_tree_comment: string;
97
+ }
98
+ /** Admin翻译草稿服务 */
99
+ export interface BaseTranslationService {
100
+ /** 为单个已保存资源生成机器翻译草稿 */
101
+ GenerateTranslationDraft(request: GenerateTranslationDraftRequest): Promise<GenerateTranslationDraftResponse>;
102
+ }
@@ -87,4 +87,6 @@ export interface SiteConfigState {
87
87
  display: SiteDisplayConfig;
88
88
  /** 当前登录验证码配置 */
89
89
  captcha: LoginCaptchaConfig;
90
+ /** 是否允许显式生成机器翻译草稿。 */
91
+ translationDraftEnabled: boolean;
90
92
  }
@@ -1,4 +1,5 @@
1
1
  export { useAuthStore } from "./modules/auth";
2
+ export { useConfigStore } from "./modules/config";
2
3
  export { useGlobalStore } from "./modules/global";
3
4
  export { useTabsStore } from "./modules/tabs";
4
5
  export { useUserStore } from "./modules/user";
@@ -2,14 +2,14 @@
2
2
  * @description:用户性别
3
3
  */
4
4
  export declare const genderType: {
5
- label: string;
5
+ readonly label: string;
6
6
  value: number;
7
7
  }[];
8
8
  /**
9
9
  * @description:用户状态
10
10
  */
11
11
  export declare const userStatus: {
12
- label: string;
12
+ readonly label: string;
13
13
  value: number;
14
14
  tagType: string;
15
15
  }[];
@@ -90,7 +90,7 @@ export declare function randomNum(min: number, max: number): number;
90
90
  * @description 获取当前时间对应的提示语
91
91
  * @returns {String}
92
92
  */
93
- export declare function getTimeState(): "早上好 ⛅" | "中午好 🌞" | "下午好 🌞" | "晚上好 🌛" | "凌晨好 🌛" | undefined;
93
+ export declare function getTimeState(): string;
94
94
  /**
95
95
  * @description 获取不同路由模式所对应的 url + params
96
96
  * @returns {String}
@@ -3,6 +3,8 @@ import { type Component } from "vue";
3
3
  export interface OauthProviderDisplay {
4
4
  /** 登录方式名称。 */
5
5
  name: string;
6
+ /** 登录方式名称对应的稳定语言键。 */
7
+ nameKey: string;
6
8
  /** 登录方式图标标识。 */
7
9
  icon: string;
8
10
  }
@@ -8,15 +8,9 @@ export interface PasswordStrengthResult {
8
8
  strengthScore: number;
9
9
  /** 强度等级。 */
10
10
  level: PasswordStrengthLevel;
11
- /** 强度文案。 */
12
- text: string;
13
11
  /** 是否达到允许提交的最高强度。 */
14
12
  isValid: boolean;
15
13
  }
16
- /** 密码强度错误提示。 */
17
- export declare const PASSWORD_STRENGTH_ERROR_MESSAGE = "\u5BC6\u7801\u9700\u540C\u65F6\u5305\u542B\u5927\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u7279\u6B8A\u5B57\u7B26\uFF0C\u4E14\u957F\u5EA6\u4E0D\u5C11\u4E8E 8 \u4F4D";
18
- /** 密码强度说明文案。 */
19
- export declare const PASSWORD_STRENGTH_TIP = "\u9700\u540C\u65F6\u5305\u542B\u5927\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u7279\u6B8A\u5B57\u7B26\uFF0C\u4E14\u957F\u5EA6\u4E0D\u5C11\u4E8E 8 \u4F4D\uFF0C\u8FBE\u5230\u6700\u9AD8\u5F3A\u5EA6\u540E\u624D\u53EF\u63D0\u4EA4\u3002";
20
14
  /**
21
15
  * 计算密码强度结果,供表单展示和校验统一复用。
22
16
  *
@@ -32,5 +26,4 @@ export declare function getPasswordStrength(password?: string): PasswordStrength
32
26
  */
33
27
  export declare function validatePasswordStrengthValue(password?: string): {
34
28
  valid: boolean;
35
- message: string;
36
29
  };
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <el-config-provider :locale="zhCn" :size="assemblySize" :button="buttonConfig">
2
+ <el-config-provider :locale="elementLocale" :size="assemblySize" :button="buttonConfig">
3
3
  <router-view></router-view>
4
4
  </el-config-provider>
5
5
  </template>
@@ -9,9 +9,18 @@ import { reactive, computed } from "vue";
9
9
  import { useTheme } from "./hooks/useTheme";
10
10
  import { ElConfigProvider } from "element-plus";
11
11
  import { useGlobalStore } from "./stores/modules/global";
12
+ import { useLocaleStore } from "./locales";
13
+ import en from "element-plus/es/locale/lang/en";
14
+ import ja from "element-plus/es/locale/lang/ja";
12
15
  import zhCn from "element-plus/es/locale/lang/zh-cn";
16
+ import zhTw from "element-plus/es/locale/lang/zh-tw";
17
+ import ko from "element-plus/es/locale/lang/ko";
18
+ import fr from "element-plus/es/locale/lang/fr";
19
+ import es from "element-plus/es/locale/lang/es";
13
20
 
14
21
  const globalStore = useGlobalStore();
22
+ const { locale } = useLocaleStore();
23
+ const elementLocale = computed(() => ({ "zh-CN": zhCn, "zh-TW": zhTw, "en-US": en, "ja-JP": ja, "ko-KR": ko, "fr-FR": fr, "es-ES": es })[locale.value]);
15
24
 
16
25
  // init theme
17
26
  const { initTheme } = useTheme();
@@ -0,0 +1,20 @@
1
+ import service from "../../utils/request";
2
+ import type { GetLanguageRequest, GetLanguageResponse, LanguageService } from "../../rpc/base/v1/language";
3
+
4
+ const LANGUAGE_URL = "/v1/base/language";
5
+
6
+ /** 语言公共服务。 */
7
+ export class LanguageServiceImpl implements LanguageService {
8
+ /** 查询当前支持的语言和主语言。 */
9
+ GetLanguage(request: GetLanguageRequest): Promise<GetLanguageResponse> {
10
+ return service<GetLanguageRequest, GetLanguageResponse>({
11
+ url: LANGUAGE_URL,
12
+ method: "get",
13
+ params: request,
14
+ headers: { Authorization: "no-auth" }
15
+ });
16
+ }
17
+ }
18
+
19
+ /** 主语言公共服务。 */
20
+ export const defLanguageService = new LanguageServiceImpl();
@@ -43,7 +43,6 @@ export class OauthServiceImpl {
43
43
  headers: { Authorization: "no-auth" }
44
44
  });
45
45
  }
46
-
47
46
  }
48
47
 
49
48
  /** defOauthService 三方登录服务实例。 */
@@ -38,7 +38,6 @@ export class AuthServiceImpl {
38
38
  params: request
39
39
  });
40
40
  }
41
-
42
41
  }
43
42
 
44
43
  /** defAuthService 管理端运行壳认证服务实例。 */
@@ -22,6 +22,13 @@ import { useConfigStore } from "./stores/modules/config";
22
22
  import { kratosAdminModule } from "./modules/kratosAdmin";
23
23
  import { registerAdminModules } from "./modules";
24
24
  import type { AdminModule } from "./modules";
25
+ import { adminI18n, applyLanguageConfig, initializeLocale, registerLocaleChangeHandler, registerLocaleMessages, t } from "./locales";
26
+ import { useAuthStore } from "./stores/modules/auth";
27
+ import { useDictStore } from "./stores/modules/dict";
28
+ import { useTabsStore } from "./stores/modules/tabs";
29
+ import { useUserStore } from "./stores/modules/user";
30
+ import { getRouteMetaTitle } from "./utils";
31
+ import { defLanguageService } from "./api/base/language";
25
32
 
26
33
  /**
27
34
  * 管理端启动参数。
@@ -37,7 +44,15 @@ export interface AdminBootstrapOptions {
37
44
  * 创建并启动管理端应用,业务项目可通过 modules 注册自己的页面。
38
45
  */
39
46
  export async function bootstrapAdminApp(options: AdminBootstrapOptions = {}) {
40
- registerAdminModules([kratosAdminModule, ...(options.modules ?? [])]);
47
+ const modules = [kratosAdminModule, ...(options.modules ?? [])];
48
+ registerAdminModules(modules);
49
+ registerLocaleMessages(modules);
50
+ initializeLocale();
51
+ try {
52
+ applyLanguageConfig(await defLanguageService.GetLanguage({}));
53
+ } catch {
54
+ // 语言公共接口失败时继续使用静态语言包和系统语言。
55
+ }
41
56
 
42
57
  const app = createApp(App);
43
58
 
@@ -56,7 +71,8 @@ export async function bootstrapAdminApp(options: AdminBootstrapOptions = {}) {
56
71
  // 按需加载模式不会自动注册 v-loading 指令,需要显式挂载。
57
72
  app.directive("loading", ElLoading.directive);
58
73
 
59
- app.use(directives).use(pinia).use(router);
74
+ app.use(directives).use(pinia).use(router).use(adminI18n);
75
+ registerLocaleChangeHandler(refreshLocalizedRuntimeData);
60
76
 
61
77
  try {
62
78
  await useConfigStore().loadDisplayConfig();
@@ -67,3 +83,42 @@ export async function bootstrapAdminApp(options: AdminBootstrapOptions = {}) {
67
83
  app.mount(options.mount ?? "#app");
68
84
  return app;
69
85
  }
86
+
87
+ /** 刷新当前语言对应的菜单、字典、页签和页面标题。 */
88
+ async function refreshLocalizedRuntimeData() {
89
+ const userStore = useUserStore(pinia);
90
+ const authStore = useAuthStore(pinia);
91
+ const dictStore = useDictStore(pinia);
92
+ const configStore = useConfigStore(pinia);
93
+ await Promise.allSettled([configStore.loadDisplayConfig()]);
94
+ if (userStore.token || userStore.refreshToken) {
95
+ await Promise.allSettled([authStore.getAuthMenuList(), dictStore.updateDictionaryCache()]);
96
+ syncLocalizedRouteState();
97
+ }
98
+ updateDocumentTitle();
99
+ }
100
+
101
+ function syncLocalizedRouteState() {
102
+ const authStore = useAuthStore(pinia);
103
+ const tabsStore = useTabsStore(pinia);
104
+ const menuMap = new Map(authStore.flatMenuListGet.flatMap(item => (item.name ? [[item.name, item] as const] : [])));
105
+
106
+ router.getRoutes().forEach(record => {
107
+ const menu = typeof record.name === "string" ? menuMap.get(record.name) : undefined;
108
+ if (menu?.meta) Object.assign(record.meta, menu.meta);
109
+ });
110
+ tabsStore.setTabs(
111
+ tabsStore.tabsMenuList.map(tab => {
112
+ const menu = menuMap.get(tab.name);
113
+ return menu ? { ...tab, title: getRouteMetaTitle(menu.meta) } : tab;
114
+ })
115
+ );
116
+ }
117
+
118
+ function updateDocumentTitle() {
119
+ const route = router.currentRoute.value;
120
+ const titleKey = typeof route.meta.titleKey === "string" ? route.meta.titleKey : "";
121
+ const routeTitle = titleKey ? t(titleKey) : String(route.meta.title ?? "");
122
+ const appTitle = import.meta.env.VITE_GLOB_APP_TITLE;
123
+ document.title = routeTitle ? `${routeTitle} - ${appTitle}` : appTitle;
124
+ }