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