@liujitcn/kratos-admin-core 0.0.62 → 0.0.64

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 (37) hide show
  1. package/README.md +2 -0
  2. package/dist/package/declarations/src/components/TreeFilter/index.vue.d.ts +1 -1
  3. package/dist/package/declarations/src/components/YamlEditor/index.vue.d.ts +23 -0
  4. package/dist/package/declarations/src/locales/generated.d.ts +60 -0
  5. package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +20 -0
  6. package/dist/package/declarations/src/rpc/google/protobuf/struct.d.ts +81 -0
  7. package/dist/package/declarations/src/rpc/system/admin/v1/base_i18n.d.ts +4 -23
  8. package/dist/package/declarations/src/runtime-messages.d.ts +2 -0
  9. package/dist/package/declarations/src/utils/conflict-message.d.ts +7 -0
  10. package/dist/package/declarations/src/utils/oauthProvider.d.ts +4 -0
  11. package/dist/package/declarations/src/utils/request-response.d.ts +9 -0
  12. package/dist/package/src/api/base/v1/file.ts +1 -1
  13. package/dist/package/src/components/YamlEditor/index.vue +107 -0
  14. package/dist/package/src/directives/modules/copy.ts +2 -1
  15. package/dist/package/src/hooks/useTable.ts +1 -1
  16. package/dist/package/src/locales/en-US.json +16 -1
  17. package/dist/package/src/locales/index.ts +3 -2
  18. package/dist/package/src/locales/ja-JP.json +16 -1
  19. package/dist/package/src/locales/zh-CN.json +16 -1
  20. package/dist/package/src/locales/zh-TW.json +16 -1
  21. package/dist/package/src/modules/index.ts +6 -5
  22. package/dist/package/src/routers/index.ts +1 -1
  23. package/dist/package/src/routers/modules/dynamicRouter.ts +1 -1
  24. package/dist/package/src/routers/modules/staticRouter.ts +2 -1
  25. package/dist/package/src/rpc/base/v1/oauth.ts +16 -0
  26. package/dist/package/src/rpc/google/protobuf/struct.ts +80 -0
  27. package/dist/package/src/rpc/system/admin/v1/base_i18n.ts +4 -24
  28. package/dist/package/src/runtime-messages.ts +39 -0
  29. package/dist/package/src/stores/modules/auth.ts +9 -4
  30. package/dist/package/src/utils/conflict-message.ts +79 -0
  31. package/dist/package/src/utils/oauthProvider.ts +9 -1
  32. package/dist/package/src/utils/request-response.ts +14 -0
  33. package/dist/package/src/utils/request.ts +10 -6
  34. package/dist/package/types/generated/components.d.ts +1 -0
  35. package/package.json +8 -1
  36. package/types/generated/components.d.ts +1 -0
  37. package/vite.config.ts +3 -4
package/README.md CHANGED
@@ -96,6 +96,7 @@ packages/core
96
96
  | `src/components/SvgIcon/` | SVG 图标渲染。 |
97
97
  | `src/components/SwitchDark/` | 明暗主题切换。 |
98
98
  | `src/components/TreeFilter/` | 树形筛选器。 |
99
+ | `src/components/YamlEditor/` | YAML 语法高亮编辑器,支持行号、缩进、折叠及自定义状态栏文案。 |
99
100
  | `src/components/TenantSelect/` | 默认租户租户选择器,普通租户自动隐藏。 |
100
101
  | `src/components/TenantText/` | 租户名称展示组件,支持名称选项和租户 ID 兜底。 |
101
102
  | `src/components/Upload/` | 单/多文件和单/多图片上传组件。 |
@@ -167,6 +168,7 @@ core 通过 `ADMIN_STATIC_VIEWS` 注册全部默认静态页面,后注册业
167
168
  | ProTable Adapter | `@liujitcn/kratos-admin-core/components/ProTable` |
168
169
  | ProTable 类型 | `@liujitcn/kratos-admin-core/components/ProTable/interface` |
169
170
  | SearchForm | `@liujitcn/kratos-admin-core/components/SearchForm/index.vue` |
171
+ | YamlEditor | `@liujitcn/kratos-admin-core/components/YamlEditor/index.vue` |
170
172
 
171
173
  其他 Vue 组件以 `package.json#exports` 中的明确白名单为准。禁止使用 `components/ProTable/index.vue`、`utils/*`、`hooks/*`、`stores/modules/*` 等实现路径。发布构建会把内部 `@/` 别名转换成包内相对路径,内部实现不占用公共子路径。
172
174
 
@@ -5857,8 +5857,8 @@ declare const __VLS_base: import("vue").DefineComponent<TreeFilterProps, {
5857
5857
  }, string, import("vue").PublicProps, Readonly<TreeFilterProps> & Readonly<{
5858
5858
  onChange?: ((value: any) => any) | undefined;
5859
5859
  }>, {
5860
- id: string;
5861
5860
  label: string;
5861
+ id: string;
5862
5862
  lazy: boolean;
5863
5863
  multiple: boolean;
5864
5864
  showAll: boolean;
@@ -0,0 +1,23 @@
1
+ /** YAML 编辑器组件属性。 */
2
+ interface YamlEditorProps {
3
+ modelValue: string;
4
+ placeholderText?: string;
5
+ minHeight?: string;
6
+ invalid?: boolean;
7
+ lineLabel?: string;
8
+ /** 根据光标行列生成状态栏文案。 */
9
+ formatPosition?: (line: number, column: number) => string;
10
+ }
11
+ declare const __VLS_export: import("vue").DefineComponent<YamlEditorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
12
+ "update:modelValue": (value: string) => any;
13
+ }, string, import("vue").PublicProps, Readonly<YamlEditorProps> & Readonly<{
14
+ "onUpdate:modelValue"?: ((value: string) => any) | undefined;
15
+ }>, {
16
+ invalid: boolean;
17
+ minHeight: string;
18
+ placeholderText: string;
19
+ lineLabel: string;
20
+ formatPosition: (line: number, column: number) => string;
21
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
22
+ declare const _default: typeof __VLS_export;
23
+ export default _default;
@@ -63,6 +63,16 @@ export declare const LOCALE_MESSAGES: {
63
63
  "common.message.request_error": string;
64
64
  "common.message.save_success": string;
65
65
  "common.message.system_error": string;
66
+ "common.error.conflict": string;
67
+ "common.error.conflict.unique_location": string;
68
+ "common.error.conflict.resource": string;
69
+ "common.error.conflict.operation": string;
70
+ "common.error.conflict.related_resource": string;
71
+ "common.error.conflict.unknown_field": string;
72
+ "common.error.conflict.field_separator": string;
73
+ "common.error.conflict.detail_separator": string;
74
+ "common.error.conflict.with_details": string;
75
+ "common.error.rate_limited": string;
66
76
  "common.validation.phone_invalid": string;
67
77
  "common.validation.phone_required": string;
68
78
  "common.title.notice": string;
@@ -73,6 +83,8 @@ export declare const LOCALE_MESSAGES: {
73
83
  "common.placeholder.select": string;
74
84
  "common.status.disabled": string;
75
85
  "common.status.enabled": string;
86
+ "common.status.configured": string;
87
+ "common.status.not_configured": string;
76
88
  "common.value.female": string;
77
89
  "common.value.male": string;
78
90
  "common.message.unknown": string;
@@ -375,8 +387,11 @@ export declare const LOCALE_MESSAGES: {
375
387
  "common.resource.default": string;
376
388
  "common.action.delete_resource": string;
377
389
  "common.action.set_field_status": string;
390
+ "common.field.tenant_id": string;
391
+ "common.field.user_id": string;
378
392
  "core.home.demo_scope": string;
379
393
  "core.home.main_title": string;
394
+ "core.router.pending_view_unregistered": string;
380
395
  };
381
396
  readonly "en-US": {
382
397
  "common.action.back": string;
@@ -438,6 +453,16 @@ export declare const LOCALE_MESSAGES: {
438
453
  "common.message.request_error": string;
439
454
  "common.message.save_success": string;
440
455
  "common.message.system_error": string;
456
+ "common.error.conflict": string;
457
+ "common.error.conflict.unique_location": string;
458
+ "common.error.conflict.resource": string;
459
+ "common.error.conflict.operation": string;
460
+ "common.error.conflict.related_resource": string;
461
+ "common.error.conflict.unknown_field": string;
462
+ "common.error.conflict.field_separator": string;
463
+ "common.error.conflict.detail_separator": string;
464
+ "common.error.conflict.with_details": string;
465
+ "common.error.rate_limited": string;
441
466
  "common.validation.phone_invalid": string;
442
467
  "common.validation.phone_required": string;
443
468
  "common.title.notice": string;
@@ -448,6 +473,8 @@ export declare const LOCALE_MESSAGES: {
448
473
  "common.placeholder.select": string;
449
474
  "common.status.disabled": string;
450
475
  "common.status.enabled": string;
476
+ "common.status.configured": string;
477
+ "common.status.not_configured": string;
451
478
  "common.value.female": string;
452
479
  "common.value.male": string;
453
480
  "common.message.unknown": string;
@@ -750,8 +777,11 @@ export declare const LOCALE_MESSAGES: {
750
777
  "common.resource.default": string;
751
778
  "common.action.delete_resource": string;
752
779
  "common.action.set_field_status": string;
780
+ "common.field.tenant_id": string;
781
+ "common.field.user_id": string;
753
782
  "core.home.demo_scope": string;
754
783
  "core.home.main_title": string;
784
+ "core.router.pending_view_unregistered": string;
755
785
  };
756
786
  readonly "ja-JP": {
757
787
  "common.action.back": string;
@@ -813,6 +843,16 @@ export declare const LOCALE_MESSAGES: {
813
843
  "common.message.request_error": string;
814
844
  "common.message.save_success": string;
815
845
  "common.message.system_error": string;
846
+ "common.error.conflict": string;
847
+ "common.error.conflict.unique_location": string;
848
+ "common.error.conflict.resource": string;
849
+ "common.error.conflict.operation": string;
850
+ "common.error.conflict.related_resource": string;
851
+ "common.error.conflict.unknown_field": string;
852
+ "common.error.conflict.field_separator": string;
853
+ "common.error.conflict.detail_separator": string;
854
+ "common.error.conflict.with_details": string;
855
+ "common.error.rate_limited": string;
816
856
  "common.validation.phone_invalid": string;
817
857
  "common.validation.phone_required": string;
818
858
  "common.title.notice": string;
@@ -823,6 +863,8 @@ export declare const LOCALE_MESSAGES: {
823
863
  "common.placeholder.select": string;
824
864
  "common.status.disabled": string;
825
865
  "common.status.enabled": string;
866
+ "common.status.configured": string;
867
+ "common.status.not_configured": string;
826
868
  "common.value.female": string;
827
869
  "common.value.male": string;
828
870
  "common.message.unknown": string;
@@ -1125,8 +1167,11 @@ export declare const LOCALE_MESSAGES: {
1125
1167
  "common.resource.default": string;
1126
1168
  "common.action.delete_resource": string;
1127
1169
  "common.action.set_field_status": string;
1170
+ "common.field.tenant_id": string;
1171
+ "common.field.user_id": string;
1128
1172
  "core.home.demo_scope": string;
1129
1173
  "core.home.main_title": string;
1174
+ "core.router.pending_view_unregistered": string;
1130
1175
  };
1131
1176
  readonly "zh-TW": {
1132
1177
  "common.action.back": string;
@@ -1188,6 +1233,16 @@ export declare const LOCALE_MESSAGES: {
1188
1233
  "common.message.request_error": string;
1189
1234
  "common.message.save_success": string;
1190
1235
  "common.message.system_error": string;
1236
+ "common.error.conflict": string;
1237
+ "common.error.conflict.unique_location": string;
1238
+ "common.error.conflict.resource": string;
1239
+ "common.error.conflict.operation": string;
1240
+ "common.error.conflict.related_resource": string;
1241
+ "common.error.conflict.unknown_field": string;
1242
+ "common.error.conflict.field_separator": string;
1243
+ "common.error.conflict.detail_separator": string;
1244
+ "common.error.conflict.with_details": string;
1245
+ "common.error.rate_limited": string;
1191
1246
  "common.validation.phone_invalid": string;
1192
1247
  "common.validation.phone_required": string;
1193
1248
  "common.title.notice": string;
@@ -1198,6 +1253,8 @@ export declare const LOCALE_MESSAGES: {
1198
1253
  "common.placeholder.select": string;
1199
1254
  "common.status.disabled": string;
1200
1255
  "common.status.enabled": string;
1256
+ "common.status.configured": string;
1257
+ "common.status.not_configured": string;
1201
1258
  "common.value.female": string;
1202
1259
  "common.value.male": string;
1203
1260
  "common.message.unknown": string;
@@ -1500,8 +1557,11 @@ export declare const LOCALE_MESSAGES: {
1500
1557
  "common.resource.default": string;
1501
1558
  "common.action.delete_resource": string;
1502
1559
  "common.action.set_field_status": string;
1560
+ "common.field.tenant_id": string;
1561
+ "common.field.user_id": string;
1503
1562
  "core.home.demo_scope": string;
1504
1563
  "core.home.main_title": string;
1564
+ "core.router.pending_view_unregistered": string;
1505
1565
  };
1506
1566
  };
1507
1567
  export type GeneratedLocale = keyof typeof LOCALE_MESSAGES;
@@ -163,13 +163,33 @@ export interface UnbindOauthAccountRequest {
163
163
  export interface OauthProvider {
164
164
  /** 登录方式标识 */
165
165
  provider: string;
166
+ /** 登录方式名称 */
167
+ name: string;
168
+ /** 登录方式提示语 */
169
+ description: string;
170
+ /** 图标键或图片地址 */
171
+ icon: string;
172
+ /** Provider个性化配置JSON对象 */
173
+ config: {
174
+ [key: string]: any;
175
+ } | undefined;
166
176
  }
167
177
  /** 个人中心三方账号绑定信息 */
168
178
  export interface OauthBinding {
169
179
  /** 登录方式标识 */
170
180
  provider: string;
181
+ /** 登录方式名称 */
182
+ name: string;
183
+ /** 登录方式提示语 */
184
+ description: string;
171
185
  /** 是否已绑定 */
172
186
  bound: boolean;
187
+ /** 图标键或图片地址 */
188
+ icon: string;
189
+ /** Provider个性化配置JSON对象 */
190
+ config: {
191
+ [key: string]: any;
192
+ } | undefined;
173
193
  }
174
194
  /** Base三方登录公共服务 */
175
195
  export interface OauthService {
@@ -0,0 +1,81 @@
1
+ /**
2
+ * `NullValue` is a singleton enumeration to represent the null value for the
3
+ * `Value` type union.
4
+ *
5
+ * The JSON representation for `NullValue` is JSON `null`.
6
+ */
7
+ export declare enum NullValue {
8
+ /** NULL_VALUE - Null value. */
9
+ NULL_VALUE = 0
10
+ }
11
+ /**
12
+ * `Struct` represents a structured data value, consisting of fields
13
+ * which map to dynamically typed values. In some languages, `Struct`
14
+ * might be supported by a native representation. For example, in
15
+ * scripting languages like JS a struct is represented as an
16
+ * object. The details of that representation are described together
17
+ * with the proto support for the language.
18
+ *
19
+ * The JSON representation for `Struct` is JSON object.
20
+ */
21
+ export interface Struct {
22
+ /** Unordered map of dynamically typed values. */
23
+ fields: Map<string, any | undefined>;
24
+ }
25
+ export interface Struct_FieldsEntry {
26
+ key: string;
27
+ value: any | undefined;
28
+ }
29
+ /**
30
+ * `Value` represents a dynamically typed value which can be either
31
+ * null, a number, a string, a boolean, a recursive struct value, or a
32
+ * list of values. A producer of value is expected to set one of these
33
+ * variants. Absence of any variant indicates an error.
34
+ *
35
+ * The JSON representation for `Value` is JSON value.
36
+ */
37
+ export interface Value {
38
+ /** The kind of value. */
39
+ kind: //
40
+ /** Represents a null value. */
41
+ {
42
+ $case: "null_value";
43
+ null_value: NullValue;
44
+ } | //
45
+ /** Represents a double value. */
46
+ {
47
+ $case: "number_value";
48
+ number_value: number;
49
+ } | //
50
+ /** Represents a string value. */
51
+ {
52
+ $case: "string_value";
53
+ string_value: string;
54
+ } | //
55
+ /** Represents a boolean value. */
56
+ {
57
+ $case: "bool_value";
58
+ bool_value: boolean;
59
+ } | //
60
+ /** Represents a structured value. */
61
+ {
62
+ $case: "struct_value";
63
+ struct_value: {
64
+ [key: string]: any;
65
+ } | undefined;
66
+ } | //
67
+ /** Represents a repeated `Value`. */
68
+ {
69
+ $case: "list_value";
70
+ list_value: Array<any> | undefined;
71
+ } | undefined;
72
+ }
73
+ /**
74
+ * `ListValue` is a wrapper around a repeated field of values.
75
+ *
76
+ * The JSON representation for `ListValue` is JSON array.
77
+ */
78
+ export interface ListValue {
79
+ /** Repeated field of dynamically typed values. */
80
+ values: any[];
81
+ }
@@ -1,23 +1,4 @@
1
1
  import type { Empty } from "../../../google/protobuf/empty";
2
- /** 统一翻译表目标类型,和 base_i18n.target_type 的值一一对应。 */
3
- export declare enum I18nTargetType {
4
- /** I18N_TARGET_TYPE_UNSPECIFIED - 未指定统一翻译表目标类型。 */
5
- I18N_TARGET_TYPE_UNSPECIFIED = 0,
6
- /** I18N_TARGET_TYPE_BASE_CONFIG_VALUE - 系统配置值。 */
7
- I18N_TARGET_TYPE_BASE_CONFIG_VALUE = 1,
8
- /** I18N_TARGET_TYPE_BASE_CONFIG_NAME - 系统配置名称。 */
9
- I18N_TARGET_TYPE_BASE_CONFIG_NAME = 2,
10
- /** I18N_TARGET_TYPE_BASE_DICT_NAME - 字典名称。 */
11
- I18N_TARGET_TYPE_BASE_DICT_NAME = 3,
12
- /** I18N_TARGET_TYPE_BASE_DICT_ITEM_LABEL - 字典项标签。 */
13
- I18N_TARGET_TYPE_BASE_DICT_ITEM_LABEL = 4,
14
- /** I18N_TARGET_TYPE_BASE_MENU_META_TITLE - 菜单标题。 */
15
- I18N_TARGET_TYPE_BASE_MENU_META_TITLE = 5,
16
- /** I18N_TARGET_TYPE_BASE_JOB_NAME - 定时任务名称。 */
17
- I18N_TARGET_TYPE_BASE_JOB_NAME = 6,
18
- /** I18N_TARGET_TYPE_BASE_MIGRATION_DESCRIPTION - 数据库迁移说明。 */
19
- I18N_TARGET_TYPE_BASE_MIGRATION_DESCRIPTION = 7
20
- }
21
2
  /** 翻译单个文本请求。 */
22
3
  export interface DraftBaseI18nRequest {
23
4
  /** 待翻译文本 */
@@ -41,8 +22,8 @@ export interface DraftBaseI18nItem {
41
22
  export interface UpdateBaseI18nRequest {
42
23
  /** 翻译记录ID,大于零时优先按ID更新;ID不存在时根据目标信息更新或新增 */
43
24
  id: number;
44
- /** 翻译目标类型,ID为零时用于查询或新增 */
45
- target_type: I18nTargetType;
25
+ /** 翻译目标键,格式为表名.字段名 */
26
+ target_key: string;
46
27
  /** 目标资源ID,ID为零时用于查询或新增 */
47
28
  target_id: number;
48
29
  /** 目标语言区域,ID为零时用于查询或新增 */
@@ -54,8 +35,8 @@ export interface UpdateBaseI18nRequest {
54
35
  export interface BaseI18n {
55
36
  /** 翻译记录ID */
56
37
  id: number;
57
- /** 翻译目标类型 */
58
- target_type: I18nTargetType;
38
+ /** 翻译目标键,格式为表名.字段名 */
39
+ target_key: string;
59
40
  /** 目标资源ID */
60
41
  target_id: number;
61
42
  /** 语言区域 */
@@ -0,0 +1,2 @@
1
+ /** 渲染管理端无框架运行时错误。 */
2
+ export declare function runtimeMessage(key: string, params?: Record<string, string>): string;
@@ -0,0 +1,7 @@
1
+ type ConflictMessageTranslator = (key: string, params?: Record<string, string>) => string;
2
+ /** 格式化结构化冲突错误,优先显示资源和字段,缺少业务元数据时回退到接口路径。 */
3
+ export declare function formatConflictMessage(message: string, error: {
4
+ reason?: string;
5
+ metadata?: Record<string, string>;
6
+ } | undefined, translate: ConflictMessageTranslator): string;
7
+ export {};
@@ -12,6 +12,10 @@ export interface OauthProviderDisplay {
12
12
  export interface OauthProviderSource {
13
13
  /** 登录方式标识。 */
14
14
  provider: string;
15
+ /** 接口返回的动态名称。 */
16
+ name?: string;
17
+ /** 接口返回的动态图标键或图片地址。 */
18
+ icon?: string;
15
19
  }
16
20
  /** 根据 provider 标识获取前端展示信息。 */
17
21
  export declare function getOauthProviderDisplay(provider: string): OauthProviderDisplay;
@@ -0,0 +1,9 @@
1
+ /** 判断响应是否包含结构化错误码。 */
2
+ export declare function hasStructuredErrorCode<T extends object>(value: T): value is T & {
3
+ code: number;
4
+ };
5
+ /** 返回结构化错误提示,并为缺少 message 的限流响应提供本地化回退。 */
6
+ export declare function resolveStructuredErrorMessage(value: {
7
+ message?: string;
8
+ reason?: string;
9
+ }, translate: (key: string) => string): string;
@@ -65,7 +65,7 @@ export class FileServiceImpl {
65
65
  document.body.removeChild(a);
66
66
  window.URL.revokeObjectURL(url);
67
67
  } catch (error) {
68
- console.error("下载错误:", error);
68
+ console.error("File download failed:", error);
69
69
  }
70
70
  }
71
71
  }
@@ -0,0 +1,107 @@
1
+ <template>
2
+ <div class="yaml-editor">
3
+ <div ref="editorHost" class="yaml-editor__host" :class="{ 'is-invalid': invalid }" />
4
+ <div class="yaml-editor__footer">
5
+ <span>{{ statusText }}</span>
6
+ <span>{{ lineCount }} {{ lineLabel }}</span>
7
+ </div>
8
+ </div>
9
+ </template>
10
+
11
+ <script setup lang="ts">
12
+ import { onBeforeUnmount, onMounted, ref, watch } from "vue";
13
+ import { basicSetup, EditorView } from "codemirror";
14
+ import { yaml } from "@codemirror/lang-yaml";
15
+ import { placeholder } from "@codemirror/view";
16
+
17
+ /** YAML 编辑器组件属性。 */
18
+ interface YamlEditorProps {
19
+ modelValue: string;
20
+ placeholderText?: string;
21
+ minHeight?: string;
22
+ invalid?: boolean;
23
+ lineLabel?: string;
24
+ /** 根据光标行列生成状态栏文案。 */
25
+ formatPosition?: (line: number, column: number) => string;
26
+ }
27
+
28
+ const props = withDefaults(defineProps<YamlEditorProps>(), {
29
+ placeholderText: "",
30
+ minHeight: "280px",
31
+ invalid: false,
32
+ lineLabel: "lines",
33
+ formatPosition: (line: number, column: number) => `Ln ${line}, Col ${column}`
34
+ });
35
+
36
+ const emit = defineEmits<{ "update:modelValue": [value: string] }>();
37
+ const editorHost = ref<HTMLElement>();
38
+ const lineCount = ref(1);
39
+ const statusText = ref("");
40
+ let editor: EditorView | undefined;
41
+
42
+ const editorTheme = EditorView.theme({
43
+ "&": { color: "var(--el-text-color-primary)", backgroundColor: "var(--el-fill-color-blank)", fontSize: "13px" },
44
+ ".cm-content": { minHeight: props.minHeight, padding: "12px 0", caretColor: "var(--el-color-primary)" },
45
+ ".cm-gutters": { color: "var(--el-text-color-placeholder)", backgroundColor: "var(--el-fill-color-light)", border: "none", borderRight: "1px solid var(--el-border-color-lighter)" },
46
+ ".cm-activeLineGutter, .cm-activeLine": { backgroundColor: "var(--el-fill-color-lighter)" },
47
+ ".cm-cursor, .cm-dropCursor": { borderLeftColor: "var(--el-color-primary)" },
48
+ ".cm-selectionBackground, &.cm-focused .cm-selectionBackground": { backgroundColor: "var(--el-color-primary-light-8)" },
49
+ ".cm-scroller": { overflow: "auto", fontFamily: "'SFMono-Regular', Consolas, 'Liberation Mono', monospace" },
50
+ ".cm-placeholder": { color: "var(--el-text-color-placeholder)" }
51
+ }, { dark: document.documentElement.classList.contains("dark") });
52
+
53
+ onMounted(() => {
54
+ if (!editorHost.value) return;
55
+ editor = new EditorView({
56
+ doc: props.modelValue,
57
+ parent: editorHost.value,
58
+ extensions: [
59
+ basicSetup,
60
+ yaml(),
61
+ editorTheme,
62
+ EditorView.lineWrapping,
63
+ EditorView.contentAttributes.of({ "aria-label": "YAML editor", spellcheck: "false" }),
64
+ EditorView.updateListener.of(update => {
65
+ if (!update.docChanged) return;
66
+ const value = update.state.doc.toString();
67
+ lineCount.value = update.state.doc.lines;
68
+ statusText.value = "";
69
+ emit("update:modelValue", value);
70
+ }),
71
+ EditorView.domEventHandlers({
72
+ keyup: (_event, view) => {
73
+ const cursor = view.state.selection.main.head;
74
+ const line = view.state.doc.lineAt(cursor);
75
+ statusText.value = props.formatPosition(line.number, cursor - line.from + 1);
76
+ return false;
77
+ },
78
+ click: (_event, view) => {
79
+ const cursor = view.state.selection.main.head;
80
+ const line = view.state.doc.lineAt(cursor);
81
+ statusText.value = props.formatPosition(line.number, cursor - line.from + 1);
82
+ return false;
83
+ }
84
+ }),
85
+ ...(props.placeholderText ? [placeholder(props.placeholderText)] : [])
86
+ ]
87
+ });
88
+ lineCount.value = editor.state.doc.lines;
89
+ });
90
+
91
+ watch(() => props.modelValue, value => {
92
+ if (!editor || value === editor.state.doc.toString()) return;
93
+ editor.dispatch({ changes: { from: 0, to: editor.state.doc.length, insert: value } });
94
+ lineCount.value = editor.state.doc.lines;
95
+ });
96
+
97
+ onBeforeUnmount(() => editor?.destroy());
98
+ </script>
99
+
100
+ <style scoped>
101
+ .yaml-editor { width: 100%; overflow: hidden; border: 1px solid var(--el-border-color); border-radius: 4px; }
102
+ .yaml-editor:focus-within { border-color: var(--el-color-primary); }
103
+ .yaml-editor__host :deep(.cm-editor) { min-height: v-bind(minHeight); }
104
+ .yaml-editor__host :deep(.cm-editor.cm-focused) { outline: none; }
105
+ .yaml-editor__host.is-invalid { border-color: var(--el-color-danger); }
106
+ .yaml-editor__footer { display: flex; justify-content: space-between; min-height: 24px; padding: 3px 10px; color: var(--el-text-color-secondary); background: var(--el-fill-color-lighter); border-top: 1px solid var(--el-border-color-lighter); font-size: 12px; }
107
+ </style>
@@ -33,7 +33,8 @@ async function handleClick(this: any) {
33
33
  message: t("core.clipboard.success")
34
34
  });
35
35
  } catch (err) {
36
- console.error("复制操作不被支持或失败: ", err);
36
+ console.error("Clipboard write failed:", err);
37
+ ElMessage.error(t("core.markdown.message.copy_failed"));
37
38
  }
38
39
  }
39
40
 
@@ -49,7 +49,7 @@ export const useTable = (
49
49
  };
50
50
  },
51
51
  set: (newVal: any) => {
52
- console.log("我是分页更新之后的值", newVal);
52
+ console.log("Pagination parameter updated:", newVal);
53
53
  }
54
54
  });
55
55
 
@@ -58,6 +58,16 @@
58
58
  "common.message.request_error": "Request failed",
59
59
  "common.message.save_success": "Saved successfully",
60
60
  "common.message.system_error": "System error",
61
+ "common.error.conflict": "Resource state conflict",
62
+ "common.error.conflict.unique_location": "Conflict location: {resource}; fields: {fields}",
63
+ "common.error.conflict.resource": "Affected resource: {resource}",
64
+ "common.error.conflict.operation": "API endpoint: {operation}",
65
+ "common.error.conflict.related_resource": "Related location: {parent} → {child}",
66
+ "common.error.conflict.unknown_field": "unspecified field",
67
+ "common.error.conflict.field_separator": ", ",
68
+ "common.error.conflict.detail_separator": "; ",
69
+ "common.error.conflict.with_details": "{message} ({details})",
70
+ "common.error.rate_limited": "Too many requests. Please try again later.",
61
71
  "common.validation.phone_invalid": "Enter a valid phone number",
62
72
  "common.validation.phone_required": "Enter a phone number",
63
73
  "common.title.notice": "Notice",
@@ -68,6 +78,8 @@
68
78
  "common.placeholder.select": "Select a value",
69
79
  "common.status.disabled": "Disabled",
70
80
  "common.status.enabled": "Enabled",
81
+ "common.status.configured": "Configured",
82
+ "common.status.not_configured": "Not configured",
71
83
  "common.value.female": "Female",
72
84
  "common.value.male": "Male",
73
85
  "common.message.unknown": "Unknown",
@@ -370,6 +382,9 @@
370
382
  "common.resource.default": "{resource}",
371
383
  "common.action.delete_resource": "Delete {resource}",
372
384
  "common.action.set_field_status": "Set {field}",
385
+ "common.field.tenant_id": "Tenant ID",
386
+ "common.field.user_id": "User ID",
373
387
  "core.home.demo_scope": "Overview",
374
- "core.home.main_title": "Admin Application"
388
+ "core.home.main_title": "Admin Application",
389
+ "core.router.pending_view_unregistered": "The admin static page is not registered: {view}"
375
390
  }
@@ -13,6 +13,7 @@ import {
13
13
  SUPPORTED_LOCALES as GENERATED_SUPPORTED_LOCALES,
14
14
  type GeneratedLocale
15
15
  } from "./generated";
16
+ import { runtimeMessage } from "../runtime-messages";
16
17
 
17
18
  /** 管理端已打包的语言区域;运行时可切换列表由 base_language 接口决定。 */
18
19
  export const SUPPORTED_LOCALES = GENERATED_SUPPORTED_LOCALES;
@@ -92,7 +93,7 @@ export function registerLocaleMessages(modules: AdminModule[]): void {
92
93
  let message = targetMessages[key] ?? defaultMessages[key];
93
94
  assertLocaleKeyNamespace(module.name, key);
94
95
  if (Object.prototype.hasOwnProperty.call(target, key)) {
95
- throw new Error(`${locale} 语言键重复: ${key}`);
96
+ throw new Error(runtimeMessage("locale_duplicate", { locale, key }));
96
97
  }
97
98
  if (!hasMatchingLocalePlaceholders(module.name, key, message, defaultMessages[key] ?? "")) {
98
99
  message = defaultMessages[key] ?? "";
@@ -239,7 +240,7 @@ function applyLocale(locale: SupportedLocale): void {
239
240
  function assertLocaleKeyNamespace(moduleName: string, key: string): void {
240
241
  const valid =
241
242
  moduleName === "kratos-admin" ? key.startsWith("common.") || key.startsWith("core.") : key.startsWith(`${moduleName}.`);
242
- if (!valid) throw new Error(`${moduleName} 的语言键命名空间无效: ${key}`);
243
+ if (!valid) throw new Error(runtimeMessage("locale_namespace_invalid", { module: moduleName, key }));
243
244
  }
244
245
 
245
246
  function requiredLocaleKeys(messages: LocaleMessages): string[] {
@@ -58,6 +58,16 @@
58
58
  "common.message.request_error": "リクエストに失敗しました",
59
59
  "common.message.save_success": "保存しました",
60
60
  "common.message.system_error": "システムエラー",
61
+ "common.error.conflict": "リソースの状態がこの操作と競合しています",
62
+ "common.error.conflict.unique_location": "競合箇所:{resource};フィールド:{fields}",
63
+ "common.error.conflict.resource": "対象リソース:{resource}",
64
+ "common.error.conflict.operation": "API エンドポイント:{operation}",
65
+ "common.error.conflict.related_resource": "関連箇所:{parent} → {child}",
66
+ "common.error.conflict.unknown_field": "フィールド未特定",
67
+ "common.error.conflict.field_separator": "、",
68
+ "common.error.conflict.detail_separator": ";",
69
+ "common.error.conflict.with_details": "{message}({details})",
70
+ "common.error.rate_limited": "リクエストが多すぎます。しばらくしてからもう一度お試しください。",
61
71
  "common.validation.phone_invalid": "正しい携帯電話番号を入力してください",
62
72
  "common.validation.phone_required": "携帯電話番号を入力してください",
63
73
  "common.title.notice": "ヒント",
@@ -68,6 +78,8 @@
68
78
  "common.placeholder.select": "選択してください",
69
79
  "common.status.disabled": "無効",
70
80
  "common.status.enabled": "有効にする",
81
+ "common.status.configured": "設定済み",
82
+ "common.status.not_configured": "未設定",
71
83
  "common.value.female": "女性",
72
84
  "common.value.male": "男性",
73
85
  "common.message.unknown": "不明",
@@ -370,6 +382,9 @@
370
382
  "common.resource.default": "{resource}",
371
383
  "common.action.delete_resource": "{resource}を削除",
372
384
  "common.action.set_field_status": "{field}を設定",
385
+ "common.field.tenant_id": "テナント ID",
386
+ "common.field.user_id": "ユーザー ID",
373
387
  "core.home.demo_scope": "機能概要",
374
- "core.home.main_title": "管理アプリケーション"
388
+ "core.home.main_title": "管理アプリケーション",
389
+ "core.router.pending_view_unregistered": "管理画面の静的ページが登録されていません: {view}"
375
390
  }