@liujitcn/kratos-admin-system 0.0.20 → 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 (86) hide show
  1. package/README.md +51 -50
  2. package/dist/package/declarations/src/api/system/base_language.d.ts +51 -0
  3. package/dist/package/declarations/src/api/system/base_translation.d.ts +7 -0
  4. package/dist/package/declarations/src/api/system/code_gen_i18n.d.ts +8 -0
  5. package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +39 -0
  6. package/dist/package/declarations/src/components/DynamicTranslationEditor.vue.d.ts +23 -0
  7. package/dist/package/declarations/src/components/dynamicTranslation.d.ts +44 -0
  8. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +5 -0
  9. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +79 -0
  10. package/dist/package/declarations/src/rpc/system/admin/v1/base_language.d.ts +114 -0
  11. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +40 -0
  12. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +102 -0
  13. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +2 -0
  14. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +7 -0
  15. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +13 -0
  16. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +23 -0
  17. package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +7 -7
  18. package/dist/package/declarations/src/views/tool/language/index.vue.d.ts +3 -0
  19. package/dist/package/src/api/base/ai_message.ts +7 -12
  20. package/dist/package/src/api/base/sse.ts +3 -1
  21. package/dist/package/src/api/system/base_language.ts +137 -0
  22. package/dist/package/src/api/system/base_translation.ts +22 -0
  23. package/dist/package/src/api/system/code_gen_column.ts +17 -3
  24. package/dist/package/src/api/system/code_gen_i18n.ts +18 -0
  25. package/dist/package/src/api/system/code_gen_table.ts +12 -4
  26. package/dist/package/src/components/DynamicTranslationCell.vue +176 -0
  27. package/dist/package/src/components/DynamicTranslationEditor.vue +166 -0
  28. package/dist/package/src/components/dynamicTranslation.ts +86 -0
  29. package/dist/package/src/locales/README.md +28 -0
  30. package/dist/package/src/locales/en-US.json +929 -0
  31. package/dist/package/src/locales/es-ES.json +928 -0
  32. package/dist/package/src/locales/fr-FR.json +928 -0
  33. package/dist/package/src/locales/ja-JP.json +929 -0
  34. package/dist/package/src/locales/ko-KR.json +928 -0
  35. package/dist/package/src/locales/zh-CN.json +929 -0
  36. package/dist/package/src/locales/zh-TW.json +928 -0
  37. package/dist/package/src/module.ts +19 -1
  38. package/dist/package/src/rpc/system/admin/v1/base_config.ts +5 -0
  39. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +81 -0
  40. package/dist/package/src/rpc/system/admin/v1/base_language.ts +135 -0
  41. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +41 -0
  42. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +117 -0
  43. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +5 -1
  44. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +8 -0
  45. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +15 -0
  46. package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +1 -6
  47. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +70 -53
  48. package/dist/package/src/views/ai/chat/components/SessionPanel.vue +20 -9
  49. package/dist/package/src/views/ai/chat/components/XSender.vue +36 -23
  50. package/dist/package/src/views/ai/chat/index.vue +55 -39
  51. package/dist/package/src/views/ai/chat/message.ts +18 -17
  52. package/dist/package/src/views/base/api/index.vue +121 -83
  53. package/dist/package/src/views/base/area/index.vue +81 -31
  54. package/dist/package/src/views/base/config/index.vue +272 -78
  55. package/dist/package/src/views/base/dept/index.vue +110 -61
  56. package/dist/package/src/views/base/dict/index.vue +137 -58
  57. package/dist/package/src/views/base/dict/item.vue +147 -61
  58. package/dist/package/src/views/base/job/index.vue +134 -81
  59. package/dist/package/src/views/base/job/log.vue +21 -22
  60. package/dist/package/src/views/base/log/index.vue +68 -46
  61. package/dist/package/src/views/base/menu/index.vue +257 -156
  62. package/dist/package/src/views/base/migration/index.vue +49 -29
  63. package/dist/package/src/views/base/post/index.vue +128 -59
  64. package/dist/package/src/views/base/role/index.vue +145 -78
  65. package/dist/package/src/views/base/tenant/index.vue +132 -63
  66. package/dist/package/src/views/base/user/components/dept-tree.vue +2 -1
  67. package/dist/package/src/views/base/user/index.vue +192 -112
  68. package/dist/package/src/views/profile/components/base.vue +44 -27
  69. package/dist/package/src/views/profile/components/password.vue +43 -27
  70. package/dist/package/src/views/profile/components/security.vue +89 -53
  71. package/dist/package/src/views/profile/index.vue +10 -9
  72. package/dist/package/src/views/tool/api-doc/index.vue +6 -2
  73. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +30 -14
  74. package/dist/package/src/views/tool/code-gen/columns/index.vue +382 -273
  75. package/dist/package/src/views/tool/code-gen/columns/option-copy.ts +1 -6
  76. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +118 -0
  77. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +65 -36
  78. package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +8 -5
  79. package/dist/package/src/views/tool/code-gen/config.ts +114 -77
  80. package/dist/package/src/views/tool/code-gen/preview/data.ts +19 -17
  81. package/dist/package/src/views/tool/code-gen/preview/index.vue +96 -58
  82. package/dist/package/src/views/tool/code-gen/proto/index.vue +110 -62
  83. package/dist/package/src/views/tool/code-gen/table/index.vue +197 -117
  84. package/dist/package/src/views/tool/language/index.vue +256 -0
  85. package/dist/package/src/views/tool/project-doc/index.vue +17 -15
  86. package/package.json +6 -2
@@ -12,32 +12,60 @@
12
12
  <FormDialog
13
13
  v-model="dialog.visible"
14
14
  ref="formDialogRef"
15
- :title="dialog.title"
16
- width="500px"
15
+ :title="t(dialog.editing ? 'system.dict.action.edit' : 'system.dict.action.create')"
16
+ width="700px"
17
17
  :model="formData"
18
18
  :fields="formFields"
19
19
  :rules="rules"
20
20
  label-width="100px"
21
21
  @confirm="handleSubmit"
22
22
  @close="handleCloseDialog"
23
- />
23
+ >
24
+ <template #translations>
25
+ <DynamicTranslationEditor
26
+ v-model="translationValues"
27
+ :resource-id="formData.id"
28
+ :resource-type="TranslationResourceType.TRANSLATION_RESOURCE_TYPE_DICT"
29
+ :draft-enabled="configStore.translationDraftEnabled"
30
+ :maxlength="50"
31
+ />
32
+ </template>
33
+ </FormDialog>
24
34
  </div>
25
35
  </template>
26
36
 
27
37
  <script setup lang="ts">
28
- import { computed, reactive, ref } from "vue";
38
+ import { computed, h, reactive, ref } from "vue";
29
39
  import { ElMessage, ElMessageBox } from "element-plus";
30
40
  import { CirclePlus, Delete, EditPen, List } from "@element-plus/icons-vue";
31
- import type { ColumnProps, HeaderActionProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
41
+ import type {
42
+ ColumnProps,
43
+ HeaderActionProps,
44
+ ProTableInstance,
45
+ RenderScope
46
+ } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
32
47
  import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
33
48
  import FormDialog from "@liujitcn/kratos-admin-core/components/Dialog/FormDialog.vue";
34
49
  import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
35
50
  import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
36
51
  import { defBaseDictService } from "@liujitcn/kratos-admin-system/api/system/base_dict";
52
+ import { loadEnabledBaseLanguages } from "@liujitcn/kratos-admin-system/api/system/base_language";
37
53
  import type { BaseDict, BaseDictForm, PageBaseDictRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_dict";
38
54
  import router, { navigateTo } from "@liujitcn/kratos-admin-core/navigation";
39
55
  import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
40
56
  import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
57
+ import { t } from "@liujitcn/kratos-admin-core";
58
+ import { useConfigStore } from "@liujitcn/kratos-admin-core/stores/runtime";
59
+ import DynamicTranslationEditor from "@liujitcn/kratos-admin-system/components/DynamicTranslationEditor.vue";
60
+ import DynamicTranslationCell from "@liujitcn/kratos-admin-system/components/DynamicTranslationCell.vue";
61
+ import {
62
+ normalizeDynamicTranslations,
63
+ serializeDynamicTranslations,
64
+ type DynamicTranslationRecord,
65
+ type DynamicTranslationValue
66
+ } from "@liujitcn/kratos-admin-system/components/dynamicTranslation";
67
+ import { TranslationResourceType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_translation";
68
+ import type { BaseDictTranslation } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_dict";
41
69
 
42
70
  defineOptions({
43
71
  name: "BaseDict",
@@ -45,11 +73,13 @@ defineOptions({
45
73
  });
46
74
 
47
75
  const { BUTTONS } = useAuthButtons();
76
+ const configStore = useConfigStore();
48
77
  const proTable = ref<ProTableInstance>();
49
78
  const formDialogRef = ref<InstanceType<typeof FormDialog>>();
79
+ const translationValues = ref<DynamicTranslationValue[]>(normalizeDynamicTranslations(undefined, "name"));
50
80
 
51
81
  const dialog = reactive({
52
- title: "",
82
+ editing: false,
53
83
  visible: false
54
84
  });
55
85
 
@@ -60,65 +90,109 @@ const formData = reactive<BaseDictForm>({
60
90
  code: "",
61
91
  /** 字典名称 */
62
92
  name: "",
93
+ /** 非主语言翻译 */
94
+ translations: [],
63
95
  /** 状态 */
64
96
  status: Status.ENABLE
65
97
  });
66
98
 
67
99
  const rules = computed(() => ({
68
100
  name: [
69
- { required: true, message: "请输入字典名称", trigger: "blur" },
70
- { max: 50, message: "字典名称不能超过 50 个字符", trigger: "blur" }
101
+ { required: true, message: t("system.dict.placeholder.name"), trigger: "blur" },
102
+ {
103
+ max: 50,
104
+ message: t("system.common.validation.maxLength", { field: t("system.dict.field.name"), max: 50 }),
105
+ trigger: "blur"
106
+ }
71
107
  ],
72
108
  code: [
73
- { required: true, message: "请输入字典编码", trigger: "blur" },
74
- { max: 50, message: "字典编号不能超过 50 个字符", trigger: "blur" }
109
+ { required: true, message: t("system.dict.placeholder.code"), trigger: "blur" },
110
+ {
111
+ max: 50,
112
+ message: t("system.common.validation.maxLength", { field: t("system.dict.field.code"), max: 50 }),
113
+ trigger: "blur"
114
+ }
75
115
  ],
76
- status: [{ required: true, message: "状态不能为空", trigger: "change" }]
116
+ status: [
117
+ {
118
+ required: true,
119
+ message: t("system.common.validation.requiredSelect", { field: t("system.common.field.status") }),
120
+ trigger: "change"
121
+ }
122
+ ]
77
123
  }));
78
124
 
79
- const statusOptions: ProFormOption[] = [
80
- { label: "启用", value: Status.ENABLE },
81
- { label: "禁用", value: Status.DISABLE }
82
- ];
125
+ const statusOptions = computed<ProFormOption[]>(() => [
126
+ { label: t("common.status.enabled"), value: Status.ENABLE },
127
+ { label: t("common.status.disabled"), value: Status.DISABLE }
128
+ ]);
83
129
 
84
130
  /** 字典表单字段配置。 */
85
- const formFields: ProFormField[] = [
86
- { prop: "name", label: "字典名称", component: "input", props: { placeholder: "请输入字典名称" } },
87
- { prop: "code", label: "字典编码", component: "input", props: { placeholder: "请输入字典编码" } },
88
- { prop: "status", label: "状态", component: "radio-group", options: statusOptions }
89
- ];
131
+ const formFields = computed<ProFormField[]>(() => [
132
+ {
133
+ prop: "name",
134
+ label: t("system.dict.field.name"),
135
+ component: "input",
136
+ props: { placeholder: t("system.dict.placeholder.name") }
137
+ },
138
+ {
139
+ prop: "code",
140
+ label: t("system.dict.field.code"),
141
+ component: "input",
142
+ props: { placeholder: t("system.dict.placeholder.code") }
143
+ },
144
+ { prop: "translations", label: t("system.translation.field.translations"), component: "slot", slotName: "translations" },
145
+ { prop: "status", label: t("system.common.field.status"), component: "radio-group", options: statusOptions.value }
146
+ ]);
147
+
148
+ /** 渲染字典名称翻译预览,并复用当前页面的编辑弹窗。 */
149
+ function renderDictNameCell(scope: RenderScope<BaseDict>) {
150
+ const row = scope.row;
151
+ return h(DynamicTranslationCell, {
152
+ source: row.name,
153
+ translations: row.translations,
154
+ textField: "name"
155
+ });
156
+ }
90
157
 
91
158
  /** 字典表格列配置。 */
92
- const columns: ColumnProps[] = [
159
+ const columns = computed<ColumnProps[]>(() => [
93
160
  { type: "selection", width: 55 },
94
- { prop: "name", label: "字典名称", minWidth: 140, search: { el: "input" } },
95
- { prop: "code", label: "字典编码", minWidth: 160, search: { el: "input" } },
161
+ {
162
+ prop: "name",
163
+ label: t("system.dict.field.name"),
164
+ minWidth: 140,
165
+ search: { el: "input" },
166
+ showOverflowTooltip: false,
167
+ render: scope => renderDictNameCell(scope as unknown as RenderScope<BaseDict>)
168
+ },
169
+ { prop: "code", label: t("system.dict.field.code"), minWidth: 160, search: { el: "input" } },
96
170
  {
97
171
  prop: "status",
98
- label: "状态",
172
+ label: t("system.common.field.status"),
99
173
  minWidth: 100,
100
174
  search: { el: "select" },
101
175
  cellType: "status",
102
176
  statusProps: {
103
177
  activeValue: Status.ENABLE,
104
178
  inactiveValue: Status.DISABLE,
105
- activeText: "启用",
106
- inactiveText: "禁用",
179
+ activeText: t("common.status.enabled"),
180
+ inactiveText: t("common.status.disabled"),
107
181
  disabled: () => !BUTTONS.value["base:dict:status"],
108
182
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseDict)
109
183
  }
110
184
  },
111
- { prop: "created_at", label: "创建时间", minWidth: 180 },
112
- { prop: "updated_at", label: "更新时间", minWidth: 180 },
185
+ { prop: "created_at", label: t("system.common.field.createdAt"), minWidth: 180 },
186
+ { prop: "updated_at", label: t("system.common.field.updatedAt"), minWidth: 180 },
113
187
  {
114
188
  prop: "operation",
115
- label: "操作",
189
+ label: t("system.common.field.action"),
116
190
  width: 240,
117
191
  fixed: "right",
118
192
  cellType: "actions",
119
193
  actions: [
120
194
  {
121
- label: "字典数据",
195
+ label: t("system.dict.action.items"),
122
196
  type: "primary",
123
197
  link: true,
124
198
  icon: List,
@@ -126,7 +200,7 @@ const columns: ColumnProps[] = [
126
200
  onClick: scope => handleOpenBaseDictItem(scope.row as BaseDict)
127
201
  },
128
202
  {
129
- label: "编辑",
203
+ label: t("common.action.edit"),
130
204
  type: "primary",
131
205
  link: true,
132
206
  icon: EditPen,
@@ -135,7 +209,7 @@ const columns: ColumnProps[] = [
135
209
  onClick: (scope, params) => handleOpenDialog((params?.dictId as number | undefined) ?? (scope.row as BaseDict).id)
136
210
  },
137
211
  {
138
- label: "删除",
212
+ label: t("common.action.delete"),
139
213
  type: "danger",
140
214
  link: true,
141
215
  icon: Delete,
@@ -144,31 +218,32 @@ const columns: ColumnProps[] = [
144
218
  }
145
219
  ]
146
220
  }
147
- ];
221
+ ]);
148
222
 
149
223
  /** 字典顶部按钮配置。 */
150
- const headerActions: HeaderActionProps[] = [
224
+ const headerActions = computed<HeaderActionProps[]>(() => [
151
225
  {
152
- label: "新增",
226
+ label: t("common.action.create"),
153
227
  type: "success",
154
228
  icon: CirclePlus,
155
229
  hidden: () => !BUTTONS.value["base:dict:create"],
156
230
  onClick: () => handleOpenDialog()
157
231
  },
158
232
  {
159
- label: "删除",
233
+ label: t("common.action.delete"),
160
234
  type: "danger",
161
235
  icon: Delete,
162
236
  hidden: () => !BUTTONS.value["base:dict:delete"],
163
237
  disabled: scope => !scope.selectedList.length,
164
238
  onClick: scope => handleDelete(scope.selectedList as BaseDict[])
165
239
  }
166
- ];
240
+ ]);
167
241
 
168
242
  /**
169
243
  * 请求字典列表,并由 ProTable 统一管理分页搜索。
170
244
  */
171
245
  async function requestBaseDictTable(params: PageBaseDictRequest) {
246
+ await loadEnabledBaseLanguages();
172
247
  const data = await defBaseDictService.PageBaseDict(buildPageRequest(params));
173
248
  return { data: { list: data.base_dicts ?? [], total: data.total } };
174
249
  }
@@ -183,15 +258,16 @@ function refreshTable() {
183
258
  /**
184
259
  * 打开字典编辑弹窗。
185
260
  */
186
- function handleOpenDialog(dictId?: number) {
261
+ async function handleOpenDialog(dictId?: number) {
262
+ await loadEnabledBaseLanguages();
187
263
  resetForm();
188
- dialog.title = dictId ? "修改字典" : "新增字典";
264
+ dialog.editing = Boolean(dictId);
189
265
  dialog.visible = true;
190
266
  if (!dictId) return;
191
267
 
192
- defBaseDictService.GetBaseDict({ id: dictId }).then(data => {
193
- Object.assign(formData, data);
194
- });
268
+ const data = await defBaseDictService.GetBaseDict({ id: dictId });
269
+ Object.assign(formData, data);
270
+ translationValues.value = normalizeDynamicTranslations(data.translations as DynamicTranslationRecord[], "name");
195
271
  }
196
272
 
197
273
  /**
@@ -211,7 +287,9 @@ function resetForm() {
211
287
  formData.id = 0;
212
288
  formData.code = "";
213
289
  formData.name = "";
290
+ formData.translations = [];
214
291
  formData.status = Status.ENABLE;
292
+ translationValues.value = normalizeDynamicTranslations(undefined, "name");
215
293
  }
216
294
 
217
295
  /**
@@ -222,11 +300,12 @@ function handleSubmit() {
222
300
  if (!isValid) return;
223
301
 
224
302
  const submitData = JSON.parse(JSON.stringify(formData)) as BaseDictForm;
303
+ submitData.translations = serializeDynamicTranslations(translationValues.value, "name") as unknown as BaseDictTranslation[];
225
304
  const request = submitData.id
226
305
  ? defBaseDictService.UpdateBaseDict({ base_dict: submitData })
227
306
  : defBaseDictService.CreateBaseDict({ base_dict: submitData });
228
307
  request.then(() => {
229
- ElMessage.success(submitData.id ? "修改字典成功" : "新增字典成功");
308
+ ElMessage.success(t(submitData.id ? "system.dict.message.updateSuccess" : "system.dict.message.createSuccess"));
230
309
  handleCloseDialog();
231
310
  refreshTable();
232
311
  });
@@ -238,16 +317,16 @@ function handleSubmit() {
238
317
  */
239
318
  async function handleBeforeSetStatus(row: BaseDict) {
240
319
  const nextStatus = row.status === Status.ENABLE ? Status.DISABLE : Status.ENABLE;
241
- const text = nextStatus === Status.ENABLE ? "启用" : "禁用";
320
+ const action = t(nextStatus === Status.ENABLE ? "common.status.enabled" : "common.status.disabled");
242
321
  const dictName = row.name || row.code || String(row.id);
243
322
  try {
244
- await ElMessageBox.confirm(`是否确定${text}字典?\n字典名称:${dictName}`, "提示", {
245
- confirmButtonText: "确认",
246
- cancelButtonText: "取消",
323
+ await ElMessageBox.confirm(t("system.dict.message.confirmStatus", { action, name: dictName }), t("common.title.notice"), {
324
+ confirmButtonText: t("common.action.confirm"),
325
+ cancelButtonText: t("common.action.cancel"),
247
326
  type: "warning"
248
327
  });
249
328
  await defBaseDictService.SetBaseDictStatus({ id: row.id, status: nextStatus });
250
- ElMessage.success(`${text}成功`);
329
+ ElMessage.success(t("system.common.message.statusSuccess", { action }));
251
330
  refreshTable();
252
331
  return true;
253
332
  } catch {
@@ -268,29 +347,29 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
268
347
  dictList.length ? dictList.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>)
269
348
  ).join(",");
270
349
  if (!dictIds) {
271
- ElMessage.warning("请勾选删除项");
350
+ ElMessage.warning(t("system.common.message.selectDeleteItem"));
272
351
  return;
273
352
  }
274
353
 
275
354
  const confirmMessage = dictList.length
276
355
  ? dictList.length === 1
277
- ? `是否确定删除字典?\n字典名称:${dictList[0].name || dictList[0].code || `ID:${dictList[0].id}`}`
278
- : `确认删除已选中的 ${dictList.length} 个字典吗?`
279
- : "确认删除已选中的字典吗?";
356
+ ? t("system.dict.message.confirmDeleteSingle", { name: dictList[0].name || dictList[0].code || `ID:${dictList[0].id}` })
357
+ : t("system.dict.message.confirmDeleteBatch", { count: dictList.length })
358
+ : t("system.dict.message.confirmDeleteSelected");
280
359
 
281
- ElMessageBox.confirm(confirmMessage, "警告", {
282
- confirmButtonText: "确定",
283
- cancelButtonText: "取消",
360
+ ElMessageBox.confirm(confirmMessage, t("common.title.warning"), {
361
+ confirmButtonText: t("common.action.confirm"),
362
+ cancelButtonText: t("common.action.cancel"),
284
363
  type: "warning"
285
364
  }).then(
286
365
  () => {
287
366
  defBaseDictService.DeleteBaseDict({ id: dictIds }).then(() => {
288
- ElMessage.success("删除字典成功");
367
+ ElMessage.success(t("system.dict.message.deleteSuccess"));
289
368
  refreshTable();
290
369
  });
291
370
  },
292
371
  () => {
293
- ElMessage.info("已取消删除字典");
372
+ ElMessage.info(t("system.dict.message.deleteCanceled"));
294
373
  }
295
374
  );
296
375
  }
@@ -299,6 +378,6 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
299
378
  * 打开字典数据页面。
300
379
  */
301
380
  function handleOpenBaseDictItem(row: BaseDict) {
302
- navigateTo(router, "/base/dict/item", { dictId: row.id, title: `【${row.name}】字典数据` });
381
+ navigateTo(router, "/base/dict/item", { dictId: row.id, title: t("system.dict.title.items", { name: row.name }) });
303
382
  }
304
383
  </script>