@liujitcn/kratos-admin-system 0.0.20 → 0.0.23

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 (118) hide show
  1. package/README.md +51 -50
  2. package/dist/package/declarations/src/api/system/base_language.d.ts +52 -0
  3. package/dist/package/declarations/src/api/system/base_translation.d.ts +10 -0
  4. package/dist/package/declarations/src/api/system/code_gen_i18n.d.ts +8 -0
  5. package/dist/package/declarations/src/api/system/ops_monitoring.d.ts +19 -0
  6. package/dist/package/declarations/src/api/system/ops_monitoring_sse.d.ts +12 -0
  7. package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +16 -0
  8. package/dist/package/declarations/src/components/DynamicTranslationEditor.vue.d.ts +20 -0
  9. package/dist/package/declarations/src/components/dynamicTranslation.d.ts +38 -0
  10. package/dist/package/declarations/src/locales/generated.d.ts +6536 -0
  11. package/dist/package/declarations/src/rpc/base/v1/ai_session.d.ts +12 -2
  12. package/dist/package/declarations/src/rpc/base/v1/ai_tool.d.ts +9 -1
  13. package/dist/package/declarations/src/rpc/base/v1/config.d.ts +35 -0
  14. package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +1 -1
  15. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +23 -2
  16. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +9 -0
  17. package/dist/package/declarations/src/rpc/system/admin/v1/base_job.d.ts +9 -1
  18. package/dist/package/declarations/src/rpc/system/admin/v1/base_language.d.ts +119 -0
  19. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +6 -1
  20. package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +6 -6
  21. package/dist/package/declarations/src/rpc/system/admin/v1/base_role.d.ts +13 -1
  22. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +75 -0
  23. package/dist/package/declarations/src/rpc/system/admin/v1/base_user.d.ts +11 -1
  24. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +13 -11
  25. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +7 -0
  26. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +24 -1
  27. package/dist/package/declarations/src/rpc/system/admin/v1/common.d.ts +13 -0
  28. package/dist/package/declarations/src/rpc/system/admin/v1/ops_monitoring.d.ts +222 -0
  29. package/dist/package/declarations/src/views/base/language/index.vue.d.ts +3 -0
  30. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +23 -0
  31. package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +7 -7
  32. package/dist/package/declarations/src/views/tool/ops-monitoring/index.vue.d.ts +3 -0
  33. package/dist/package/src/api/base/ai_message.ts +7 -12
  34. package/dist/package/src/api/base/sse.ts +3 -1
  35. package/dist/package/src/api/system/base_language.ts +135 -0
  36. package/dist/package/src/api/system/base_translation.ts +33 -0
  37. package/dist/package/src/api/system/code_gen_column.ts +17 -3
  38. package/dist/package/src/api/system/code_gen_i18n.ts +18 -0
  39. package/dist/package/src/api/system/code_gen_table.ts +12 -4
  40. package/dist/package/src/api/system/ops_monitoring.ts +88 -0
  41. package/dist/package/src/api/system/ops_monitoring_sse.ts +49 -0
  42. package/dist/package/src/components/DynamicTranslationCell.vue +249 -0
  43. package/dist/package/src/components/DynamicTranslationEditor.vue +197 -0
  44. package/dist/package/src/components/dynamicTranslation.ts +66 -0
  45. package/dist/package/src/locales/README.md +30 -0
  46. package/dist/package/src/locales/en-US.json +933 -0
  47. package/dist/package/src/locales/es-ES.json +933 -0
  48. package/dist/package/src/locales/fr-FR.json +933 -0
  49. package/dist/package/src/locales/generated.ts +22 -0
  50. package/dist/package/src/locales/ja-JP.json +933 -0
  51. package/dist/package/src/locales/ko-KR.json +933 -0
  52. package/dist/package/src/locales/zh-CN.json +933 -0
  53. package/dist/package/src/locales/zh-TW.json +933 -0
  54. package/dist/package/src/module.ts +6 -2
  55. package/dist/package/src/rpc/base/v1/ai_session.ts +13 -2
  56. package/dist/package/src/rpc/base/v1/ai_tool.ts +10 -1
  57. package/dist/package/src/rpc/base/v1/config.ts +47 -0
  58. package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
  59. package/dist/package/src/rpc/system/admin/v1/base_config.ts +24 -2
  60. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +9 -0
  61. package/dist/package/src/rpc/system/admin/v1/base_job.ts +10 -1
  62. package/dist/package/src/rpc/system/admin/v1/base_language.ts +141 -0
  63. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +6 -1
  64. package/dist/package/src/rpc/system/admin/v1/base_migration.ts +8 -8
  65. package/dist/package/src/rpc/system/admin/v1/base_role.ts +14 -1
  66. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +90 -0
  67. package/dist/package/src/rpc/system/admin/v1/base_user.ts +12 -1
  68. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +16 -12
  69. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +8 -0
  70. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +27 -1
  71. package/dist/package/src/rpc/system/admin/v1/common.ts +21 -0
  72. package/dist/package/src/rpc/system/admin/v1/ops_monitoring.ts +255 -0
  73. package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +1 -6
  74. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +75 -58
  75. package/dist/package/src/views/ai/chat/components/SessionPanel.vue +20 -9
  76. package/dist/package/src/views/ai/chat/components/XSender.vue +36 -23
  77. package/dist/package/src/views/ai/chat/index.vue +58 -41
  78. package/dist/package/src/views/ai/chat/message.ts +29 -27
  79. package/dist/package/src/views/base/api/index.vue +121 -84
  80. package/dist/package/src/views/base/area/index.vue +81 -32
  81. package/dist/package/src/views/base/config/index.vue +300 -96
  82. package/dist/package/src/views/base/dept/index.vue +110 -62
  83. package/dist/package/src/views/base/dict/index.vue +145 -62
  84. package/dist/package/src/views/base/dict/item.vue +155 -64
  85. package/dist/package/src/views/base/job/index.vue +134 -82
  86. package/dist/package/src/views/base/job/log.vue +24 -25
  87. package/dist/package/src/views/base/language/index.vue +260 -0
  88. package/dist/package/src/views/base/log/index.vue +68 -46
  89. package/dist/package/src/views/base/menu/index.vue +344 -200
  90. package/dist/package/src/views/base/migration/index.vue +49 -29
  91. package/dist/package/src/views/base/post/index.vue +128 -60
  92. package/dist/package/src/views/base/role/index.vue +145 -79
  93. package/dist/package/src/views/base/tenant/index.vue +132 -64
  94. package/dist/package/src/views/base/user/components/dept-tree.vue +2 -1
  95. package/dist/package/src/views/base/user/index.vue +194 -116
  96. package/dist/package/src/views/profile/components/base.vue +45 -28
  97. package/dist/package/src/views/profile/components/password.vue +45 -30
  98. package/dist/package/src/views/profile/components/security.vue +90 -54
  99. package/dist/package/src/views/profile/index.vue +10 -9
  100. package/dist/package/src/views/tool/api-doc/index.vue +6 -2
  101. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +32 -16
  102. package/dist/package/src/views/tool/code-gen/columns/index.vue +382 -273
  103. package/dist/package/src/views/tool/code-gen/columns/option-copy.ts +1 -6
  104. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +118 -0
  105. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +65 -36
  106. package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +8 -5
  107. package/dist/package/src/views/tool/code-gen/config.ts +116 -79
  108. package/dist/package/src/views/tool/code-gen/preview/data.ts +19 -17
  109. package/dist/package/src/views/tool/code-gen/preview/index.vue +96 -59
  110. package/dist/package/src/views/tool/code-gen/proto/index.vue +110 -62
  111. package/dist/package/src/views/tool/code-gen/table/index.vue +201 -121
  112. package/dist/package/src/views/tool/ops-monitoring/index.vue +1175 -0
  113. package/dist/package/src/views/tool/project-doc/index.vue +17 -15
  114. package/package.json +6 -2
  115. package/dist/package/declarations/src/rpc/base/v1/enum.d.ts +0 -43
  116. package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +0 -67
  117. package/dist/package/src/rpc/base/v1/enum.ts +0 -54
  118. package/dist/package/src/rpc/system/common/v1/enum.ts +0 -80
@@ -4,7 +4,7 @@
4
4
  <TreeFilter
5
5
  :key="`dept-filter-${selectedTenantId ?? 0}`"
6
6
  label="name"
7
- title="部门列表"
7
+ :title="t('system.base.user.title.department_list')"
8
8
  :request-api="requestDeptTreeFilter"
9
9
  :show-all="false"
10
10
  :default-value="deptFilterValue"
@@ -26,12 +26,11 @@
26
26
  <FormDialog
27
27
  v-model="dialog.visible"
28
28
  ref="formDialogRef"
29
- :title="dialog.title"
29
+ :title="t(dialog.editing ? 'system.base.user.action.edit' : 'system.base.user.action.create')"
30
30
  width="800px"
31
31
  :model="formData"
32
32
  :fields="formFields"
33
33
  :rules="rules"
34
- label-width="90px"
35
34
  @confirm="handleSubmit"
36
35
  @close="handleCloseDialog"
37
36
  >
@@ -43,12 +42,11 @@
43
42
  <FormDialog
44
43
  v-model="resetPwdDialog.visible"
45
44
  ref="resetPwdFormDialogRef"
46
- :title="resetPwdDialog.title"
45
+ :title="t('system.base.user.title.reset_password', { name: resetPwdTargetName })"
47
46
  width="520px"
48
47
  :model="resetPwdForm"
49
48
  :fields="resetPwdFields"
50
49
  :rules="resetPwdRules"
51
- label-width="90px"
52
50
  @confirm="handleConfirmResetPassword"
53
51
  @close="handleCloseResetPasswordDialog"
54
52
  >
@@ -72,7 +70,12 @@ import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/co
72
70
  import TreeFilter from "@liujitcn/kratos-admin-core/components/TreeFilter/index.vue";
73
71
  import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
74
72
  import { defBaseUserService } from "@liujitcn/kratos-admin-system/api/system/base_user";
75
- import type { BaseUser, BaseUserForm, PageBaseUserRequest, ResetBaseUserPasswordRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_user";
73
+ import type {
74
+ BaseUser,
75
+ BaseUserForm,
76
+ PageBaseUserRequest,
77
+ ResetBaseUserPasswordRequest
78
+ } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_user";
76
79
  import { defBaseDeptService } from "@liujitcn/kratos-admin-system/api/system/base_dept";
77
80
  import { defBaseRoleService } from "@liujitcn/kratos-admin-system/api/system/base_role";
78
81
  import { defBasePostService } from "@liujitcn/kratos-admin-system/api/system/base_post";
@@ -80,14 +83,10 @@ import { defBaseTenantService } from "@liujitcn/kratos-admin-system/api/system/b
80
83
  import type { SelectOptionResponse_Option, TreeOptionResponse_Option } from "@liujitcn/kratos-admin-system/rpc/common/v1/common";
81
84
  import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
82
85
  import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
83
- import {
84
- PASSWORD_CRYPTO_SCENE,
85
- PASSWORD_STRENGTH_ERROR_MESSAGE,
86
- encryptPassword,
87
- validatePasswordStrengthValue
88
- } from "@liujitcn/kratos-admin-core/security";
86
+ import { PASSWORD_CRYPTO_SCENE, encryptPassword, validatePasswordStrengthValue } from "@liujitcn/kratos-admin-core/security";
89
87
  import { DEFAULT_TENANT_CODE, requestTenantOptions } from "@liujitcn/kratos-admin-core/tenant";
90
88
  import { useUserStore } from "@liujitcn/kratos-admin-core/stores/runtime";
89
+ import { t } from "@liujitcn/kratos-admin-core";
91
90
 
92
91
  /** 用户表单状态,前端保留明文密码并在提交前加密。 */
93
92
  interface BaseUserFormState extends Omit<BaseUserForm, "dept_id" | "post_id" | "pwd" | "role_id" | "tenant_id"> {
@@ -135,11 +134,10 @@ const deptFilterValue = ref("");
135
134
 
136
135
  const dialog = reactive({
137
136
  visible: false,
138
- title: "新增用户"
137
+ editing: false
139
138
  });
140
139
  const resetPwdDialog = reactive({
141
- visible: false,
142
- title: "重置密码"
140
+ visible: false
143
141
  });
144
142
 
145
143
  const formData = reactive<BaseUserFormState>({
@@ -178,66 +176,120 @@ const resetPwdForm = reactive<ResetBaseUserPasswordFormState>({
178
176
  });
179
177
  const resetPwdTargetName = ref("");
180
178
 
181
- const rules = reactive({
182
- tenant_id: [{ required: true, message: "所属租户不能为空", trigger: "change" }],
179
+ const rules = computed(() => ({
180
+ tenant_id: [
181
+ {
182
+ required: true,
183
+ message: t("common.validation.required_select", { field: t("system.base.user.field.tenant") }),
184
+ trigger: "change"
185
+ }
186
+ ],
183
187
  user_name: [
184
- { required: true, message: "用户账号不能为空", trigger: "blur" },
185
- { max: 50, message: "用户账号不能超过 50 个字符", trigger: "blur" }
188
+ {
189
+ required: true,
190
+ message: t("common.validation.required_input", { field: t("system.base.user.field.user_name") }),
191
+ trigger: "blur"
192
+ },
193
+ {
194
+ max: 50,
195
+ message: t("common.validation.max_length", { field: t("system.base.user.field.user_name"), max: 50 }),
196
+ trigger: "blur"
197
+ }
186
198
  ],
187
199
  user_code: [
188
- { required: true, message: "用户编号不能为空", trigger: "blur" },
189
- { max: 30, message: "用户编号不能超过 30 个字符", trigger: "blur" }
200
+ {
201
+ required: true,
202
+ message: t("common.validation.required_input", { field: t("system.base.user.field.user_code") }),
203
+ trigger: "blur"
204
+ },
205
+ {
206
+ max: 30,
207
+ message: t("common.validation.max_length", { field: t("system.base.user.field.user_code"), max: 30 }),
208
+ trigger: "blur"
209
+ }
190
210
  ],
191
211
  nick_name: [
192
- { required: true, message: "用户昵称不能为空", trigger: "blur" },
193
- { max: 30, message: "用户昵称不能超过 30 个字符", trigger: "blur" }
212
+ {
213
+ required: true,
214
+ message: t("common.validation.required_input", { field: t("system.base.user.field.nick_name") }),
215
+ trigger: "blur"
216
+ },
217
+ {
218
+ max: 30,
219
+ message: t("common.validation.max_length", { field: t("system.base.user.field.nick_name"), max: 30 }),
220
+ trigger: "blur"
221
+ }
222
+ ],
223
+ dept_id: [
224
+ {
225
+ required: true,
226
+ message: t("common.validation.required_select", { field: t("system.base.user.field.department") }),
227
+ trigger: "change"
228
+ }
229
+ ],
230
+ role_id: [
231
+ {
232
+ required: true,
233
+ message: t("common.validation.required_select", { field: t("system.base.user.field.role") }),
234
+ trigger: "change"
235
+ }
194
236
  ],
195
- dept_id: [{ required: true, message: "用户部门不能为空", trigger: "change" }],
196
- role_id: [{ required: true, message: "用户角色不能为空", trigger: "change" }],
197
237
  phone: [
198
- { max: 20, message: "手机号不能超过 20 个字符", trigger: "blur" },
238
+ { max: 20, message: t("common.validation.max_length", { field: t("common.field.phone"), max: 20 }), trigger: "blur" },
199
239
  {
200
240
  pattern: /^1[3-9]\d{9}$/,
201
- message: "请输入正确的手机号码",
241
+ message: t("common.validation.phone_invalid"),
202
242
  trigger: "blur"
203
243
  }
204
244
  ],
205
245
  pwd: [
206
- { required: true, message: "请输入密码", trigger: "blur" },
246
+ { required: true, message: t("core.password.required"), trigger: "blur" },
207
247
  { validator: validatePasswordField, trigger: "blur" }
208
248
  ],
209
- status: [{ required: true, message: "用户状态不能为空", trigger: "change" }],
210
- remark: [{ max: 500, message: "备注不能超过 500 个字符", trigger: "blur" }]
211
- });
212
- const resetPwdRules = reactive({
249
+ status: [
250
+ {
251
+ required: true,
252
+ message: t("common.validation.required_select", { field: t("common.field.status") }),
253
+ trigger: "change"
254
+ }
255
+ ],
256
+ remark: [
257
+ {
258
+ max: 500,
259
+ message: t("common.validation.max_length", { field: t("common.field.remark"), max: 500 }),
260
+ trigger: "blur"
261
+ }
262
+ ]
263
+ }));
264
+ const resetPwdRules = computed(() => ({
213
265
  pwd: [
214
- { required: true, message: "请输入新密码", trigger: "blur" },
266
+ { required: true, message: t("system.base.user.placeholder.new_password"), trigger: "blur" },
215
267
  { validator: validatePasswordField, trigger: "blur" }
216
268
  ]
217
- });
269
+ }));
218
270
 
219
271
  const basedDeptOptions = ref<TreeOptionResponse_Option[]>([]);
220
272
  const baseRoleOptions = ref<SelectOptionResponse_Option[]>([]);
221
273
  const basePostOptions = ref<SelectOptionResponse_Option[]>([]);
222
274
  const tenantOptions = ref<SelectOptionResponse_Option[]>([]);
223
- const statusOptions: ProFormOption[] = [
224
- { label: "启用", value: Status.ENABLE },
225
- { label: "禁用", value: Status.DISABLE }
226
- ];
227
- const resetPwdFields: ProFormField[] = [
275
+ const statusOptions = computed<ProFormOption[]>(() => [
276
+ { label: t("common.status.enabled"), value: Status.ENABLE },
277
+ { label: t("common.status.disabled"), value: Status.DISABLE }
278
+ ]);
279
+ const resetPwdFields = computed<ProFormField[]>(() => [
228
280
  {
229
281
  prop: "pwd",
230
- label: "新密码",
282
+ label: t("system.base.user.field.new_password"),
231
283
  component: "password",
232
- props: { placeholder: "请输入新密码", showPassword: true }
284
+ props: { placeholder: t("system.base.user.placeholder.new_password"), showPassword: true }
233
285
  },
234
286
  {
235
287
  prop: "resetPwdStrength",
236
- label: "强度提示",
288
+ label: t("system.base.user.field.password_strength"),
237
289
  component: "slot",
238
290
  slotName: "resetPwdStrength"
239
291
  }
240
- ];
292
+ ]);
241
293
 
242
294
  /** 当前登录账号是否默认租户。 */
243
295
  const isDefaultTenant = computed(() => userStore.userInfo.tenant_code === DEFAULT_TENANT_CODE);
@@ -255,10 +307,10 @@ const isSuperEditUser = computed(() => Boolean(formData.id && formData.user_name
255
307
  const formFields = computed<ProFormField[]>(() => [
256
308
  {
257
309
  prop: "tenant_id",
258
- label: "所属租户",
310
+ label: t("system.base.user.field.tenant"),
259
311
  component: "select",
260
312
  props: {
261
- placeholder: "请选择所属租户",
313
+ placeholder: t("system.base.user.placeholder.tenant"),
262
314
  filterable: true,
263
315
  disabled: Boolean(formData.id),
264
316
  onChange: handleFormTenantChange
@@ -268,31 +320,36 @@ const formFields = computed<ProFormField[]>(() => [
268
320
  },
269
321
  {
270
322
  prop: "user_name",
271
- label: "用户账号",
323
+ label: t("system.base.user.field.user_name"),
272
324
  component: "input",
273
- props: { placeholder: "请输入用户账号", disabled: Boolean(formData.id) }
325
+ props: { placeholder: t("system.base.user.placeholder.user_name"), disabled: Boolean(formData.id) }
274
326
  },
275
327
  {
276
328
  prop: "user_code",
277
- label: "用户编号",
329
+ label: t("system.base.user.field.user_code"),
278
330
  component: "input",
279
- props: { placeholder: "请输入用户编号", disabled: Boolean(formData.id) }
331
+ props: { placeholder: t("system.base.user.placeholder.user_code"), disabled: Boolean(formData.id) }
332
+ },
333
+ {
334
+ prop: "nick_name",
335
+ label: t("system.base.user.field.nick_name"),
336
+ component: "input",
337
+ props: { placeholder: t("system.base.user.placeholder.nick_name") }
280
338
  },
281
- { prop: "nick_name", label: "用户昵称", component: "input", props: { placeholder: "请输入用户昵称" } },
282
339
  {
283
340
  prop: "role_id",
284
- label: "角色",
341
+ label: t("system.base.user.field.role"),
285
342
  component: "select",
286
343
  options: baseRoleOptions.value.map(item => ({ label: item.label, value: item.value, disabled: item.disabled })),
287
- props: { placeholder: "请选择", disabled: isProtectedUserRole.value }
344
+ props: { placeholder: t("common.placeholder.select"), disabled: isProtectedUserRole.value }
288
345
  },
289
346
  {
290
347
  prop: "dept_id",
291
- label: "用户部门",
348
+ label: t("system.base.user.field.department"),
292
349
  component: "tree-select",
293
350
  options: basedDeptOptions.value as unknown as ProFormOption[],
294
351
  props: {
295
- placeholder: "请选择用户部门",
352
+ placeholder: t("system.base.user.placeholder.department"),
296
353
  filterable: true,
297
354
  checkStrictly: true,
298
355
  renderAfterExpand: false,
@@ -301,35 +358,45 @@ const formFields = computed<ProFormField[]>(() => [
301
358
  },
302
359
  {
303
360
  prop: "post_id",
304
- label: "用户岗位",
361
+ label: t("system.base.user.field.post"),
305
362
  component: "select",
306
363
  options: basePostOptions.value.map(item => ({ label: item.label, value: item.value, disabled: item.disabled })),
307
- props: { placeholder: "请选择用户岗位", clearable: true, filterable: true }
364
+ props: { placeholder: t("system.base.user.placeholder.post"), clearable: true, filterable: true }
365
+ },
366
+ {
367
+ prop: "phone",
368
+ label: t("common.field.phone"),
369
+ component: "input",
370
+ props: { placeholder: t("common.validation.phone_required") }
308
371
  },
309
- { prop: "phone", label: "手机号码", component: "input", props: { placeholder: "请输入手机号码" } },
310
372
  {
311
373
  prop: "pwd",
312
- label: "密码",
374
+ label: t("system.base.user.field.password"),
313
375
  component: "password",
314
- props: { placeholder: "请输入密码", showPassword: true },
376
+ props: { placeholder: t("system.base.user.placeholder.password"), showPassword: true },
315
377
  visible: model => !model.id
316
378
  },
317
379
  {
318
380
  prop: "passwordStrength",
319
- label: "强度提示",
381
+ label: t("system.base.user.field.password_strength"),
320
382
  component: "slot",
321
383
  slotName: "passwordStrength",
322
384
  visible: model => !model.id
323
385
  },
324
- { prop: "gender", label: "性别", component: "dict", props: { code: "base_user_gender" } },
386
+ { prop: "gender", label: t("system.base.user.field.gender"), component: "dict", props: { code: "base_user_gender" } },
325
387
  {
326
388
  prop: "status",
327
- label: "状态",
389
+ label: t("common.field.status"),
328
390
  component: "radio-group",
329
- options: statusOptions,
391
+ options: statusOptions.value,
330
392
  props: { disabled: isSuperEditUser.value }
331
393
  },
332
- { prop: "remark", label: "备注", component: "textarea", props: { placeholder: "请输入备注" } }
394
+ {
395
+ prop: "remark",
396
+ label: t("common.field.remark"),
397
+ component: "textarea",
398
+ props: { placeholder: t("common.placeholder.remark") }
399
+ }
333
400
  ]);
334
401
 
335
402
  /** 用户表格列配置。 */
@@ -339,7 +406,7 @@ const columns = computed<ColumnProps[]>(() => [
339
406
  ? ([
340
407
  {
341
408
  prop: "tenant_id",
342
- label: "租户",
409
+ label: t("system.base.user.field.tenant_short"),
343
410
  minWidth: 140,
344
411
  showOverflowTooltip: true,
345
412
  search: { el: "select", key: "tenant_id", props: { filterable: true }, order: 1 },
@@ -347,41 +414,54 @@ const columns = computed<ColumnProps[]>(() => [
347
414
  }
348
415
  ] satisfies ColumnProps[])
349
416
  : []),
350
- { prop: "user_name", label: "用户账号", minWidth: 140, search: { el: "input" } },
351
- { prop: "user_code", label: "用户编号", minWidth: 140, search: { el: "input" } },
352
- { prop: "nick_name", label: "昵称", minWidth: 100, search: { el: "input" } },
353
- { prop: "role_id", label: "角色", minWidth: 140, enum: requestRoleOptions },
354
- { prop: "dept_id", label: "部门", minWidth: 180, showOverflowTooltip: true, enum: requestDeptOptions },
355
- { prop: "post_id", label: "岗位", minWidth: 120, enum: requestPostOptions },
356
- { prop: "phone", label: "手机号码", minWidth: 130, search: { el: "input" } },
357
- { prop: "gender", label: "性别", minWidth: 90, align: "center", dictCode: "base_user_gender", search: { el: "select" } },
417
+ { prop: "user_name", label: t("system.base.user.field.user_name"), minWidth: 140, search: { el: "input" } },
418
+ { prop: "user_code", label: t("system.base.user.field.user_code"), minWidth: 140, search: { el: "input" } },
419
+ { prop: "nick_name", label: t("system.base.user.field.nick_name_short"), minWidth: 100, search: { el: "input" } },
420
+ { prop: "role_id", label: t("system.base.user.field.role"), minWidth: 140, enum: requestRoleOptions },
421
+ {
422
+ prop: "dept_id",
423
+ label: t("system.base.user.field.department_short"),
424
+ minWidth: 180,
425
+ showOverflowTooltip: true,
426
+ enum: requestDeptOptions
427
+ },
428
+ { prop: "post_id", label: t("system.base.user.field.post_short"), minWidth: 120, enum: requestPostOptions },
429
+ { prop: "phone", label: t("common.field.phone"), minWidth: 130, search: { el: "input" } },
430
+ {
431
+ prop: "gender",
432
+ label: t("system.base.user.field.gender"),
433
+ minWidth: 90,
434
+ align: "center",
435
+ dictCode: "base_user_gender",
436
+ search: { el: "select" }
437
+ },
358
438
  {
359
439
  prop: "status",
360
- label: "状态",
440
+ label: t("common.field.status"),
361
441
  minWidth: 100,
362
442
  search: { el: "select" },
363
443
  cellType: "status",
364
444
  statusProps: {
365
445
  activeValue: Status.ENABLE,
366
446
  inactiveValue: Status.DISABLE,
367
- activeText: "启用",
368
- inactiveText: "禁用",
447
+ activeText: t("common.status.enabled"),
448
+ inactiveText: t("common.status.disabled"),
369
449
  disabled: scope => isProtectedManagementUser(scope.row as BaseUser) || !BUTTONS.value["base:user:status"],
370
450
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseUser)
371
451
  }
372
452
  },
373
- { prop: "remark", label: "备注", minWidth: 160 },
374
- { prop: "created_at", label: "创建时间", minWidth: 180 },
375
- { prop: "updated_at", label: "更新时间", minWidth: 180 },
453
+ { prop: "remark", label: t("common.field.remark"), minWidth: 160 },
454
+ { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
455
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
376
456
  {
377
457
  prop: "operation",
378
- label: "操作",
458
+ label: t("common.field.action"),
379
459
  width: 260,
380
460
  fixed: "right",
381
461
  cellType: "actions",
382
462
  actions: [
383
463
  {
384
- label: "重置密码",
464
+ label: t("system.base.user.action.reset_password"),
385
465
  type: "primary",
386
466
  link: true,
387
467
  icon: RefreshLeft,
@@ -389,7 +469,7 @@ const columns = computed<ColumnProps[]>(() => [
389
469
  onClick: scope => handleResetPassword(scope.row as BaseUser)
390
470
  },
391
471
  {
392
- label: "编辑",
472
+ label: t("common.action.edit"),
393
473
  type: "primary",
394
474
  link: true,
395
475
  icon: EditPen,
@@ -398,7 +478,7 @@ const columns = computed<ColumnProps[]>(() => [
398
478
  onClick: (scope, params) => handleOpenDialog((params?.userId as number | undefined) ?? (scope.row as BaseUser).id)
399
479
  },
400
480
  {
401
- label: "删除",
481
+ label: t("common.action.delete"),
402
482
  type: "danger",
403
483
  link: true,
404
484
  icon: Delete,
@@ -410,23 +490,23 @@ const columns = computed<ColumnProps[]>(() => [
410
490
  ]);
411
491
 
412
492
  /** 用户顶部按钮配置。 */
413
- const headerActions: HeaderActionProps[] = [
493
+ const headerActions = computed<HeaderActionProps[]>(() => [
414
494
  {
415
- label: "新增",
495
+ label: t("common.action.create"),
416
496
  type: "success",
417
497
  icon: CirclePlus,
418
498
  hidden: () => !BUTTONS.value["base:user:create"],
419
499
  onClick: () => handleOpenDialog()
420
500
  },
421
501
  {
422
- label: "删除",
502
+ label: t("common.action.delete"),
423
503
  type: "danger",
424
504
  icon: Delete,
425
505
  hidden: () => !BUTTONS.value["base:user:delete"],
426
506
  disabled: scope => !scope.selectedList.length,
427
507
  onClick: scope => handleDelete(scope.selectedList as BaseUser[])
428
508
  }
429
- ];
509
+ ]);
430
510
 
431
511
  /**
432
512
  * 递归转换部门树筛选数据,适配 TreeFilter 组件的 id/name 字段。
@@ -442,10 +522,7 @@ function transformDeptFilterNodes(options: TreeOptionResponse_Option[] = []): De
442
522
  /**
443
523
  * 将部门树选项转换为完整路径标签,便于扁平列表关联字段按部门 ID 映射展示。
444
524
  */
445
- function transformDeptOptionPaths(
446
- options: TreeOptionResponse_Option[] = [],
447
- parentPath = ""
448
- ): TreeOptionResponse_Option[] {
525
+ function transformDeptOptionPaths(options: TreeOptionResponse_Option[] = [], parentPath = ""): TreeOptionResponse_Option[] {
449
526
  return options.map(option => {
450
527
  const label = option.label || "";
451
528
  const fullPath = [parentPath, label].filter(Boolean).join("/");
@@ -574,7 +651,7 @@ async function handleFormTenantChange() {
574
651
  async function handleOpenDialog(id?: number) {
575
652
  resetForm();
576
653
  await loadTenantOptions();
577
- dialog.title = id ? "修改用户" : "新增用户";
654
+ dialog.editing = Boolean(id);
578
655
  dialog.visible = true;
579
656
  if (!id) {
580
657
  await loadFormOptions();
@@ -629,7 +706,6 @@ function handleResetPassword(row: BaseUser) {
629
706
  resetPwdForm.id = row.id;
630
707
  resetPwdForm.pwd = "";
631
708
  resetPwdTargetName.value = row.nick_name || row.user_name || `ID:${row.id}`;
632
- resetPwdDialog.title = `重置密码:${resetPwdTargetName.value}`;
633
709
  resetPwdDialog.visible = true;
634
710
  }
635
711
 
@@ -652,9 +728,9 @@ async function handleConfirmResetPassword() {
652
728
  resetPwdFormDialogRef.value?.validate()?.then(async valid => {
653
729
  if (!valid) return;
654
730
 
655
- const pwd = await encryptPassword(resetPwdForm.pwd, PASSWORD_CRYPTO_SCENE.RESET_BASE_USER_PASSWORD);
731
+ const pwd = await encryptPassword(resetPwdForm.pwd, PASSWORD_CRYPTO_SCENE.PASSWORD_CRYPTO_SCENE_RESET_BASE_USER_PASSWORD);
656
732
  defBaseUserService.ResetBaseUserPassword({ id: resetPwdForm.id, pwd }).then(() => {
657
- ElMessage.success(`重置密码成功\n用户名称:${resetPwdTargetName.value}`);
733
+ ElMessage.success(t("system.base.user.message.reset_password_success", { name: resetPwdTargetName.value }));
658
734
  handleCloseResetPasswordDialog();
659
735
  });
660
736
  });
@@ -670,13 +746,13 @@ const handleSubmit = useDebounceFn(() => {
670
746
  const submitData = JSON.parse(JSON.stringify(formData)) as BaseUserFormState;
671
747
  const baseUser = {
672
748
  ...submitData,
673
- pwd: submitData.id ? undefined : await encryptPassword(submitData.pwd, PASSWORD_CRYPTO_SCENE.CREATE_BASE_USER)
749
+ pwd: submitData.id ? undefined : await encryptPassword(submitData.pwd, PASSWORD_CRYPTO_SCENE.PASSWORD_CRYPTO_SCENE_CREATE_BASE_USER)
674
750
  } as BaseUserForm;
675
751
  const request = submitData.id
676
752
  ? defBaseUserService.UpdateBaseUser({ base_user: baseUser })
677
753
  : defBaseUserService.CreateBaseUser({ base_user: baseUser });
678
754
  request.then(() => {
679
- ElMessage.success(submitData.id ? "修改用户成功" : "新增用户成功");
755
+ ElMessage.success(t(submitData.id ? "system.base.user.message.update_success" : "system.base.user.message.create_success"));
680
756
  handleCloseDialog();
681
757
  refreshTable();
682
758
  });
@@ -688,21 +764,21 @@ const handleSubmit = useDebounceFn(() => {
688
764
  */
689
765
  async function handleBeforeSetStatus(row: BaseUser) {
690
766
  if (isProtectedManagementUser(row)) {
691
- ElMessage.warning("内置管理员账号只能通过个人中心修改");
767
+ ElMessage.warning(t("system.base.user.message.protected_account"));
692
768
  return false;
693
769
  }
694
770
 
695
771
  const nextStatus = row.status === Status.ENABLE ? Status.DISABLE : Status.ENABLE;
696
- const text = nextStatus === Status.ENABLE ? "启用" : "禁用";
697
- const user_name = row.nick_name || row.user_name || `ID:${row.id}`;
772
+ const action = t(nextStatus === Status.ENABLE ? "common.status.enabled" : "common.status.disabled");
773
+ const userName = row.nick_name || row.user_name || `ID:${row.id}`;
698
774
  try {
699
- await ElMessageBox.confirm(`是否确定${text}用户?\n用户名称:${user_name}`, "提示", {
700
- confirmButtonText: "确认",
701
- cancelButtonText: "取消",
775
+ await ElMessageBox.confirm(t("system.base.user.message.confirm_status", { action, name: userName }), t("common.title.notice"), {
776
+ confirmButtonText: t("common.action.confirm"),
777
+ cancelButtonText: t("common.action.cancel"),
702
778
  type: "warning"
703
779
  });
704
780
  await defBaseUserService.SetBaseUserStatus({ id: row.id, status: nextStatus });
705
- ElMessage.success(`${text}成功`);
781
+ ElMessage.success(t("common.message.status_success", { action }));
706
782
  refreshTable();
707
783
  return true;
708
784
  } catch {
@@ -720,36 +796,38 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
720
796
  ? [selected]
721
797
  : [];
722
798
  if (userList.some(isProtectedManagementUser)) {
723
- ElMessage.warning("内置管理员账号只能通过个人中心修改");
799
+ ElMessage.warning(t("system.base.user.message.protected_account"));
724
800
  return;
725
801
  }
726
802
  const userIds = normalizeSelectedIds(
727
803
  userList.length ? userList.map(item => item.id) : (selected as number | string | Array<number | string> | undefined)
728
804
  ).join(",");
729
805
  if (!userIds) {
730
- ElMessage.warning("请勾选删除项");
806
+ ElMessage.warning(t("common.message.select_delete_item"));
731
807
  return;
732
808
  }
733
809
 
734
810
  const confirmMessage = userList.length
735
811
  ? userList.length === 1
736
- ? `是否确定删除用户?\n用户名称:${userList[0].nick_name || userList[0].user_name || `ID:${userList[0].id}`}`
737
- : `确认删除已选中的 ${userList.length} 个用户吗?`
738
- : "确认删除已选中的用户吗?";
739
-
740
- ElMessageBox.confirm(confirmMessage, "警告", {
741
- confirmButtonText: "确定",
742
- cancelButtonText: "取消",
812
+ ? t("system.base.user.message.confirm_delete_single", {
813
+ name: userList[0].nick_name || userList[0].user_name || `ID:${userList[0].id}`
814
+ })
815
+ : t("system.base.user.message.confirm_delete_batch", { count: userList.length })
816
+ : t("system.base.user.message.confirm_delete_selected");
817
+
818
+ ElMessageBox.confirm(confirmMessage, t("common.title.warning"), {
819
+ confirmButtonText: t("common.action.confirm"),
820
+ cancelButtonText: t("common.action.cancel"),
743
821
  type: "warning"
744
822
  }).then(
745
823
  () => {
746
824
  defBaseUserService.DeleteBaseUser({ id: userIds }).then(() => {
747
- ElMessage.success("删除用户成功");
825
+ ElMessage.success(t("system.base.user.message.delete_success"));
748
826
  refreshTable();
749
827
  });
750
828
  },
751
829
  () => {
752
- ElMessage.info("已取消删除用户");
830
+ ElMessage.info(t("system.base.user.message.delete_canceled"));
753
831
  }
754
832
  );
755
833
  }
@@ -768,7 +846,7 @@ function validatePasswordField(_rule: unknown, value: string, callback: (error?:
768
846
  }
769
847
  const result = validatePasswordStrengthValue(value);
770
848
  if (!result.valid) {
771
- callback(new Error(result.message || PASSWORD_STRENGTH_ERROR_MESSAGE));
849
+ callback(new Error(t("core.password.error")));
772
850
  return;
773
851
  }
774
852
  callback();