@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.
- package/README.md +51 -50
- package/dist/package/declarations/src/api/system/base_language.d.ts +52 -0
- package/dist/package/declarations/src/api/system/base_translation.d.ts +10 -0
- package/dist/package/declarations/src/api/system/code_gen_i18n.d.ts +8 -0
- package/dist/package/declarations/src/api/system/ops_monitoring.d.ts +19 -0
- package/dist/package/declarations/src/api/system/ops_monitoring_sse.d.ts +12 -0
- package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +16 -0
- package/dist/package/declarations/src/components/DynamicTranslationEditor.vue.d.ts +20 -0
- package/dist/package/declarations/src/components/dynamicTranslation.d.ts +38 -0
- package/dist/package/declarations/src/locales/generated.d.ts +6536 -0
- package/dist/package/declarations/src/rpc/base/v1/ai_session.d.ts +12 -2
- package/dist/package/declarations/src/rpc/base/v1/ai_tool.d.ts +9 -1
- package/dist/package/declarations/src/rpc/base/v1/config.d.ts +35 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +1 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +23 -2
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +9 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_job.d.ts +9 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/base_language.d.ts +119 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +6 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +6 -6
- package/dist/package/declarations/src/rpc/system/admin/v1/base_role.d.ts +13 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +75 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_user.d.ts +11 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +13 -11
- 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 +24 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/common.d.ts +13 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/ops_monitoring.d.ts +222 -0
- package/dist/package/declarations/src/views/base/language/index.vue.d.ts +3 -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/ops-monitoring/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 +135 -0
- package/dist/package/src/api/system/base_translation.ts +33 -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/api/system/ops_monitoring.ts +88 -0
- package/dist/package/src/api/system/ops_monitoring_sse.ts +49 -0
- package/dist/package/src/components/DynamicTranslationCell.vue +249 -0
- package/dist/package/src/components/DynamicTranslationEditor.vue +197 -0
- package/dist/package/src/components/dynamicTranslation.ts +66 -0
- package/dist/package/src/locales/README.md +30 -0
- package/dist/package/src/locales/en-US.json +933 -0
- package/dist/package/src/locales/es-ES.json +933 -0
- package/dist/package/src/locales/fr-FR.json +933 -0
- package/dist/package/src/locales/generated.ts +22 -0
- package/dist/package/src/locales/ja-JP.json +933 -0
- package/dist/package/src/locales/ko-KR.json +933 -0
- package/dist/package/src/locales/zh-CN.json +933 -0
- package/dist/package/src/locales/zh-TW.json +933 -0
- package/dist/package/src/module.ts +6 -2
- package/dist/package/src/rpc/base/v1/ai_session.ts +13 -2
- package/dist/package/src/rpc/base/v1/ai_tool.ts +10 -1
- package/dist/package/src/rpc/base/v1/config.ts +47 -0
- package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
- package/dist/package/src/rpc/system/admin/v1/base_config.ts +24 -2
- package/dist/package/src/rpc/system/admin/v1/base_dict.ts +9 -0
- package/dist/package/src/rpc/system/admin/v1/base_job.ts +10 -1
- package/dist/package/src/rpc/system/admin/v1/base_language.ts +141 -0
- package/dist/package/src/rpc/system/admin/v1/base_menu.ts +6 -1
- package/dist/package/src/rpc/system/admin/v1/base_migration.ts +8 -8
- package/dist/package/src/rpc/system/admin/v1/base_role.ts +14 -1
- package/dist/package/src/rpc/system/admin/v1/base_translation.ts +90 -0
- package/dist/package/src/rpc/system/admin/v1/base_user.ts +12 -1
- package/dist/package/src/rpc/system/admin/v1/code_gen.ts +16 -12
- 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 +27 -1
- package/dist/package/src/rpc/system/admin/v1/common.ts +21 -0
- package/dist/package/src/rpc/system/admin/v1/ops_monitoring.ts +255 -0
- package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +1 -6
- package/dist/package/src/views/ai/chat/components/ChatPanel.vue +75 -58
- 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 +58 -41
- package/dist/package/src/views/ai/chat/message.ts +29 -27
- package/dist/package/src/views/base/api/index.vue +121 -84
- package/dist/package/src/views/base/area/index.vue +81 -32
- package/dist/package/src/views/base/config/index.vue +300 -96
- package/dist/package/src/views/base/dept/index.vue +110 -62
- package/dist/package/src/views/base/dict/index.vue +145 -62
- package/dist/package/src/views/base/dict/item.vue +155 -64
- package/dist/package/src/views/base/job/index.vue +134 -82
- package/dist/package/src/views/base/job/log.vue +24 -25
- package/dist/package/src/views/base/language/index.vue +260 -0
- package/dist/package/src/views/base/log/index.vue +68 -46
- package/dist/package/src/views/base/menu/index.vue +344 -200
- package/dist/package/src/views/base/migration/index.vue +49 -29
- package/dist/package/src/views/base/post/index.vue +128 -60
- package/dist/package/src/views/base/role/index.vue +145 -79
- package/dist/package/src/views/base/tenant/index.vue +132 -64
- package/dist/package/src/views/base/user/components/dept-tree.vue +2 -1
- package/dist/package/src/views/base/user/index.vue +194 -116
- package/dist/package/src/views/profile/components/base.vue +45 -28
- package/dist/package/src/views/profile/components/password.vue +45 -30
- package/dist/package/src/views/profile/components/security.vue +90 -54
- 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 +32 -16
- 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 +116 -79
- 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 -59
- package/dist/package/src/views/tool/code-gen/proto/index.vue +110 -62
- package/dist/package/src/views/tool/code-gen/table/index.vue +201 -121
- package/dist/package/src/views/tool/ops-monitoring/index.vue +1175 -0
- package/dist/package/src/views/tool/project-doc/index.vue +17 -15
- package/package.json +6 -2
- package/dist/package/declarations/src/rpc/base/v1/enum.d.ts +0 -43
- package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +0 -67
- package/dist/package/src/rpc/base/v1/enum.ts +0 -54
- package/dist/package/src/rpc/system/common/v1/enum.ts +0 -80
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<div class="table-box">
|
|
3
3
|
<ProTable
|
|
4
4
|
ref="proTable"
|
|
5
|
-
title="
|
|
5
|
+
:title="t('system.base.menu.title.list')"
|
|
6
6
|
row-key="id"
|
|
7
7
|
:indent="20"
|
|
8
8
|
:columns="columns"
|
|
@@ -16,26 +16,33 @@
|
|
|
16
16
|
<FormDialog
|
|
17
17
|
v-model="dialog.visible"
|
|
18
18
|
ref="formDialogRef"
|
|
19
|
-
:title="dialog.
|
|
19
|
+
:title="t(dialog.editing ? 'system.base.menu.action.edit' : 'system.base.menu.action.create')"
|
|
20
20
|
width="1180px"
|
|
21
21
|
:model="formData"
|
|
22
22
|
:fields="formFields"
|
|
23
23
|
:rules="rules"
|
|
24
|
-
label-width="120px"
|
|
25
24
|
:col-span="12"
|
|
26
25
|
@confirm="handleSubmit"
|
|
27
26
|
@close="handleCloseDialog"
|
|
28
27
|
>
|
|
29
28
|
<template #menuIcon>
|
|
30
|
-
<SelectIcon v-model:icon-value="menuIconValue" placeholder="
|
|
29
|
+
<SelectIcon v-model:icon-value="menuIconValue" :placeholder="t('system.base.menu.placeholder.icon')" />
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<template #translations>
|
|
33
|
+
<DynamicTranslationEditor
|
|
34
|
+
v-model="translationValues"
|
|
35
|
+
:source="formData.meta.title"
|
|
36
|
+
:maxlength="100"
|
|
37
|
+
/>
|
|
31
38
|
</template>
|
|
32
39
|
|
|
33
40
|
<template #apiTransferItem="slotScope">
|
|
34
41
|
<el-popover effect="light" trigger="hover" placement="top" width="auto">
|
|
35
42
|
<template #default>
|
|
36
|
-
<div
|
|
37
|
-
<div
|
|
38
|
-
<div
|
|
43
|
+
<div>{{ t("system.base.api.field.operation") }}:{{ slotScope.option.operation }}</div>
|
|
44
|
+
<div>{{ t("system.base.api.field.method") }}:{{ slotScope.option.method }}</div>
|
|
45
|
+
<div>{{ t("system.base.api.field.path") }}:{{ slotScope.option.path }}</div>
|
|
39
46
|
</template>
|
|
40
47
|
<template #reference>{{ slotScope.option.label }}</template>
|
|
41
48
|
</el-popover>
|
|
@@ -49,10 +56,16 @@ import { computed, h, reactive, ref, resolveComponent, resolveDynamicComponent,
|
|
|
49
56
|
import { ElIcon, ElTag, type FormRules } from "element-plus";
|
|
50
57
|
import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
|
|
51
58
|
import FormDialog from "@liujitcn/kratos-admin-core/components/Dialog/FormDialog.vue";
|
|
52
|
-
import type {
|
|
59
|
+
import type {
|
|
60
|
+
ColumnProps,
|
|
61
|
+
HeaderActionProps,
|
|
62
|
+
ProTableInstance,
|
|
63
|
+
RenderScope
|
|
64
|
+
} from "@liujitcn/kratos-admin-core/components/ProTable/interface";
|
|
53
65
|
import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
|
|
54
66
|
import SelectIcon from "@liujitcn/kratos-admin-core/components/SelectIcon/index.vue";
|
|
55
67
|
import { defBaseMenuService } from "@liujitcn/kratos-admin-system/api/system/base_menu";
|
|
68
|
+
import { loadEnabledBaseLanguages } from "@liujitcn/kratos-admin-system/api/system/base_language";
|
|
56
69
|
import { defBaseApiService } from "@liujitcn/kratos-admin-system/api/system/base_api";
|
|
57
70
|
import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
|
|
58
71
|
import type { BaseApi } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_api";
|
|
@@ -63,8 +76,18 @@ import type {
|
|
|
63
76
|
BaseMenuMeta
|
|
64
77
|
} from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_menu";
|
|
65
78
|
import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
|
|
66
|
-
import { BaseMenuType } from "@liujitcn/kratos-admin-system/rpc/system/
|
|
79
|
+
import { BaseMenuType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/common";
|
|
80
|
+
import { TranslationTargetType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_translation";
|
|
67
81
|
import { normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
|
|
82
|
+
import { t } from "@liujitcn/kratos-admin-core";
|
|
83
|
+
import DynamicTranslationEditor from "@liujitcn/kratos-admin-system/components/DynamicTranslationEditor.vue";
|
|
84
|
+
import DynamicTranslationCell from "@liujitcn/kratos-admin-system/components/DynamicTranslationCell.vue";
|
|
85
|
+
import {
|
|
86
|
+
normalizeDynamicTranslations,
|
|
87
|
+
serializeDynamicTranslations,
|
|
88
|
+
type DynamicTranslationRecord,
|
|
89
|
+
type DynamicTranslationValue
|
|
90
|
+
} from "@liujitcn/kratos-admin-system/components/dynamicTranslation";
|
|
68
91
|
|
|
69
92
|
defineOptions({
|
|
70
93
|
name: "BaseMenu",
|
|
@@ -88,11 +111,12 @@ const menuOptions = ref<ProFormOption[]>([]);
|
|
|
88
111
|
const parentMenuTypeMap = ref(new Map<number, BaseMenuType>());
|
|
89
112
|
const appMenuIds = ref(new Set<number>([APP_MENU_ROOT_ID]));
|
|
90
113
|
const apiList = ref<BaseApi[]>([]);
|
|
114
|
+
const translationValues = ref<DynamicTranslationValue[]>(normalizeDynamicTranslations(undefined, "title"));
|
|
91
115
|
|
|
92
116
|
const dialog = reactive({
|
|
93
|
-
|
|
117
|
+
editing: false,
|
|
94
118
|
visible: false,
|
|
95
|
-
parentType: BaseMenuType.
|
|
119
|
+
parentType: BaseMenuType.BASE_MENU_TYPE_UNSPECIFIED,
|
|
96
120
|
parentLocked: true
|
|
97
121
|
});
|
|
98
122
|
|
|
@@ -126,13 +150,14 @@ function createDefaultMenuForm(): MenuFormState {
|
|
|
126
150
|
return {
|
|
127
151
|
id: 0,
|
|
128
152
|
parent_id: undefined,
|
|
129
|
-
type: BaseMenuType.
|
|
153
|
+
type: BaseMenuType.BASE_MENU_TYPE_FOLDER,
|
|
130
154
|
path: "",
|
|
131
155
|
name: "",
|
|
132
156
|
component: "",
|
|
133
157
|
redirect: "",
|
|
134
158
|
meta: createDefaultMenuMeta(),
|
|
135
159
|
api: [],
|
|
160
|
+
translations: [],
|
|
136
161
|
sort: 1,
|
|
137
162
|
status: Status.ENABLE
|
|
138
163
|
};
|
|
@@ -148,12 +173,12 @@ const menuIconValue = computed({
|
|
|
148
173
|
}
|
|
149
174
|
});
|
|
150
175
|
|
|
151
|
-
const menuTypeOptions
|
|
152
|
-
{ label: "
|
|
153
|
-
{ label: "
|
|
154
|
-
{ label: "
|
|
155
|
-
{ label: "
|
|
156
|
-
];
|
|
176
|
+
const menuTypeOptions = computed<ProFormOption[]>(() => [
|
|
177
|
+
{ label: t("system.base.menu.type.folder"), value: BaseMenuType.BASE_MENU_TYPE_FOLDER },
|
|
178
|
+
{ label: t("system.base.menu.type.menu"), value: BaseMenuType.BASE_MENU_TYPE_MENU },
|
|
179
|
+
{ label: t("system.base.menu.type.button"), value: BaseMenuType.BASE_MENU_TYPE_BUTTON },
|
|
180
|
+
{ label: t("system.base.menu.type.external"), value: BaseMenuType.BASE_MENU_TYPE_EXT_LINK }
|
|
181
|
+
]);
|
|
157
182
|
|
|
158
183
|
/** 判断父节点是否属于固定移动端菜单树。 */
|
|
159
184
|
function isAppMenu(parentId?: number) {
|
|
@@ -178,8 +203,8 @@ function getMenuLevel(menuId: number) {
|
|
|
178
203
|
function canCreateChild(menu: BaseMenu) {
|
|
179
204
|
const level = getMenuLevel(menu.id);
|
|
180
205
|
if (menu.id === APP_MENU_ROOT_ID || isAppMenu(menu.parent_id)) return level >= 1 && level < 4;
|
|
181
|
-
if (menu.type === BaseMenuType.
|
|
182
|
-
if (menu.type === BaseMenuType.
|
|
206
|
+
if (menu.type === BaseMenuType.BASE_MENU_TYPE_FOLDER) return level === 1 || level === 2;
|
|
207
|
+
if (menu.type === BaseMenuType.BASE_MENU_TYPE_MENU) return level === 2 || level === 3;
|
|
183
208
|
return false;
|
|
184
209
|
}
|
|
185
210
|
|
|
@@ -187,17 +212,24 @@ function canCreateChild(menu: BaseMenu) {
|
|
|
187
212
|
const availableMenuTypeOptions = computed(() => {
|
|
188
213
|
const parentLevel = getMenuLevel(formData.parent_id ?? 0);
|
|
189
214
|
|
|
190
|
-
if (formData.id === APP_MENU_ROOT_ID)
|
|
191
|
-
|
|
192
|
-
if (formData.
|
|
193
|
-
if (
|
|
194
|
-
return menuTypeOptions.filter(
|
|
195
|
-
|
|
215
|
+
if (formData.id === APP_MENU_ROOT_ID)
|
|
216
|
+
return menuTypeOptions.value.filter(item => item.value === BaseMenuType.BASE_MENU_TYPE_FOLDER);
|
|
217
|
+
if (isAppMenu(formData.parent_id)) return menuTypeOptions.value.filter(item => item.value === BaseMenuType.BASE_MENU_TYPE_MENU);
|
|
218
|
+
if (formData.id > 0 && parentLevel === 0)
|
|
219
|
+
return menuTypeOptions.value.filter(item => item.value === BaseMenuType.BASE_MENU_TYPE_FOLDER);
|
|
220
|
+
if (dialog.parentType === BaseMenuType.BASE_MENU_TYPE_FOLDER && parentLevel === 1)
|
|
221
|
+
return menuTypeOptions.value.filter(
|
|
222
|
+
item =>
|
|
223
|
+
item.value === BaseMenuType.BASE_MENU_TYPE_FOLDER ||
|
|
224
|
+
item.value === BaseMenuType.BASE_MENU_TYPE_MENU ||
|
|
225
|
+
item.value === BaseMenuType.BASE_MENU_TYPE_EXT_LINK
|
|
226
|
+
);
|
|
227
|
+
if (dialog.parentType === BaseMenuType.BASE_MENU_TYPE_FOLDER && parentLevel === 2)
|
|
228
|
+
return menuTypeOptions.value.filter(
|
|
229
|
+
item => item.value === BaseMenuType.BASE_MENU_TYPE_MENU || item.value === BaseMenuType.BASE_MENU_TYPE_EXT_LINK
|
|
196
230
|
);
|
|
197
|
-
if (dialog.parentType === BaseMenuType.
|
|
198
|
-
return menuTypeOptions.filter(item => item.value === BaseMenuType.
|
|
199
|
-
if (dialog.parentType === BaseMenuType.MENU && (parentLevel === 2 || parentLevel === 3))
|
|
200
|
-
return menuTypeOptions.filter(item => item.value === BaseMenuType.BUTTON);
|
|
231
|
+
if (dialog.parentType === BaseMenuType.BASE_MENU_TYPE_MENU && (parentLevel === 2 || parentLevel === 3))
|
|
232
|
+
return menuTypeOptions.value.filter(item => item.value === BaseMenuType.BASE_MENU_TYPE_BUTTON);
|
|
201
233
|
return [];
|
|
202
234
|
});
|
|
203
235
|
|
|
@@ -210,22 +242,22 @@ watch(
|
|
|
210
242
|
} else if (formData.id === 0) {
|
|
211
243
|
formData.meta.app = undefined;
|
|
212
244
|
}
|
|
213
|
-
dialog.parentType = parentMenuTypeMap.value.get(formData.parent_id ?? 0) ?? BaseMenuType.
|
|
245
|
+
dialog.parentType = parentMenuTypeMap.value.get(formData.parent_id ?? 0) ?? BaseMenuType.BASE_MENU_TYPE_UNSPECIFIED;
|
|
214
246
|
if (formData.id > 0 || availableMenuTypeOptions.value.some(item => item.value === formData.type)) return;
|
|
215
|
-
formData.type = (availableMenuTypeOptions.value[0]?.value as BaseMenuType) ?? BaseMenuType.
|
|
247
|
+
formData.type = (availableMenuTypeOptions.value[0]?.value as BaseMenuType) ?? BaseMenuType.BASE_MENU_TYPE_UNSPECIFIED;
|
|
216
248
|
}
|
|
217
249
|
);
|
|
218
250
|
|
|
219
|
-
const statusOptions
|
|
220
|
-
{ label: "
|
|
221
|
-
{ label: "
|
|
222
|
-
];
|
|
251
|
+
const statusOptions = computed<ProFormOption[]>(() => [
|
|
252
|
+
{ label: t("common.status.enabled"), value: Status.ENABLE },
|
|
253
|
+
{ label: t("common.status.disabled"), value: Status.DISABLE }
|
|
254
|
+
]);
|
|
223
255
|
|
|
224
|
-
const appAccessOptions
|
|
225
|
-
{ label: "
|
|
226
|
-
{ label: "
|
|
227
|
-
{ label: "
|
|
228
|
-
];
|
|
256
|
+
const appAccessOptions = computed<ProFormOption[]>(() => [
|
|
257
|
+
{ label: t("system.base.menu.access.public"), value: "PUBLIC" },
|
|
258
|
+
{ label: t("system.base.menu.access.guest"), value: "GUEST_ONLY" },
|
|
259
|
+
{ label: t("system.base.menu.access.authenticated"), value: "AUTHENTICATED" }
|
|
260
|
+
]);
|
|
229
261
|
|
|
230
262
|
/**
|
|
231
263
|
* 渲染菜单图标单元格,统一兼容 Element Plus 图标和本地 svg 图标。
|
|
@@ -252,7 +284,20 @@ function renderMenuIconCell(scope: RenderScope<BaseMenu>) {
|
|
|
252
284
|
*/
|
|
253
285
|
function renderHiddenCell(scope: RenderScope<BaseMenu>) {
|
|
254
286
|
const isHidden = Boolean(scope.row.meta?.hidden);
|
|
255
|
-
return h(ElTag, { type: isHidden ? "info" : "success" }, () =>
|
|
287
|
+
return h(ElTag, { type: isHidden ? "info" : "success" }, () =>
|
|
288
|
+
t(isHidden ? "system.base.menu.status.hidden" : "system.base.menu.status.visible")
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/** 渲染菜单标题翻译预览,并复用当前页面的编辑弹窗。 */
|
|
293
|
+
function renderMenuTitleCell(scope: RenderScope<BaseMenu>) {
|
|
294
|
+
const row = scope.row;
|
|
295
|
+
return h(DynamicTranslationCell, {
|
|
296
|
+
source: row.meta?.title ?? "",
|
|
297
|
+
targetType: TranslationTargetType.TRANSLATION_TARGET_TYPE_BASE_MENU,
|
|
298
|
+
targetId: row.id,
|
|
299
|
+
translations: row.translations
|
|
300
|
+
});
|
|
256
301
|
}
|
|
257
302
|
|
|
258
303
|
/** 菜单表格列配置。 */
|
|
@@ -267,26 +312,28 @@ const columns = computed<ColumnProps[]>(() => [
|
|
|
267
312
|
},
|
|
268
313
|
{
|
|
269
314
|
prop: "meta.title",
|
|
270
|
-
label: "
|
|
315
|
+
label: t("system.base.menu.field.name"),
|
|
271
316
|
minWidth: 220,
|
|
272
317
|
align: "left",
|
|
273
|
-
search: { el: "input", key: "title" }
|
|
318
|
+
search: { el: "input", key: "title" },
|
|
319
|
+
showOverflowTooltip: false,
|
|
320
|
+
render: scope => renderMenuTitleCell(scope as unknown as RenderScope<BaseMenu>)
|
|
274
321
|
},
|
|
275
|
-
{ prop: "type", label: "
|
|
322
|
+
{ prop: "type", label: t("system.base.menu.field.type"), minWidth: 120, dictCode: "base_menu_type", search: { el: "select" } },
|
|
276
323
|
{
|
|
277
324
|
prop: "meta.icon",
|
|
278
|
-
label: "
|
|
325
|
+
label: t("system.base.menu.field.icon"),
|
|
279
326
|
width: 90,
|
|
280
327
|
render: scope => renderMenuIconCell(scope as unknown as RenderScope<BaseMenu>)
|
|
281
328
|
},
|
|
282
|
-
{ prop: "path", label: "
|
|
283
|
-
{ prop: "name", label: "
|
|
284
|
-
{ prop: "component", label: "
|
|
285
|
-
{ prop: "redirect", label: "
|
|
286
|
-
{ prop: "sort", label: "
|
|
329
|
+
{ prop: "path", label: t("system.base.menu.field.path_or_permission"), minWidth: 260, search: { el: "input" } },
|
|
330
|
+
{ prop: "name", label: t("system.base.menu.field.route_name"), minWidth: 180, search: { el: "input" } },
|
|
331
|
+
{ prop: "component", label: t("system.base.menu.field.component"), minWidth: 260 },
|
|
332
|
+
{ prop: "redirect", label: t("system.base.menu.field.redirect"), minWidth: 220 },
|
|
333
|
+
{ prop: "sort", label: t("common.field.sort"), minWidth: 80, align: "right" },
|
|
287
334
|
{
|
|
288
335
|
prop: "status",
|
|
289
|
-
label: "
|
|
336
|
+
label: t("common.field.status"),
|
|
290
337
|
width: 100,
|
|
291
338
|
dictCode: "status",
|
|
292
339
|
search: { el: "select" },
|
|
@@ -294,29 +341,29 @@ const columns = computed<ColumnProps[]>(() => [
|
|
|
294
341
|
statusProps: {
|
|
295
342
|
activeValue: Status.ENABLE,
|
|
296
343
|
inactiveValue: Status.DISABLE,
|
|
297
|
-
activeText: "
|
|
298
|
-
inactiveText: "
|
|
344
|
+
activeText: t("common.status.enabled"),
|
|
345
|
+
inactiveText: t("common.status.disabled"),
|
|
299
346
|
disabled: () => !BUTTONS.value["base:menu:status"],
|
|
300
347
|
beforeChange: scope => handleBeforeSetStatus(scope.row as BaseMenu)
|
|
301
348
|
}
|
|
302
349
|
},
|
|
303
350
|
{
|
|
304
351
|
prop: "meta.hidden",
|
|
305
|
-
label: "
|
|
352
|
+
label: t("system.base.menu.field.display_status"),
|
|
306
353
|
width: 100,
|
|
307
354
|
render: scope => renderHiddenCell(scope as unknown as RenderScope<BaseMenu>)
|
|
308
355
|
},
|
|
309
|
-
{ prop: "created_at", label: "
|
|
310
|
-
{ prop: "updated_at", label: "
|
|
356
|
+
{ prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
|
|
357
|
+
{ prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
|
|
311
358
|
{
|
|
312
359
|
prop: "operation",
|
|
313
|
-
label: "
|
|
360
|
+
label: t("common.field.action"),
|
|
314
361
|
width: 220,
|
|
315
362
|
fixed: "right",
|
|
316
363
|
cellType: "actions",
|
|
317
364
|
actions: [
|
|
318
365
|
{
|
|
319
|
-
label: "
|
|
366
|
+
label: t("common.action.create"),
|
|
320
367
|
type: "primary",
|
|
321
368
|
link: true,
|
|
322
369
|
icon: CirclePlus,
|
|
@@ -324,7 +371,7 @@ const columns = computed<ColumnProps[]>(() => [
|
|
|
324
371
|
onClick: scope => handleOpenDialog(scope.row as BaseMenu)
|
|
325
372
|
},
|
|
326
373
|
{
|
|
327
|
-
label: "
|
|
374
|
+
label: t("common.action.edit"),
|
|
328
375
|
type: "primary",
|
|
329
376
|
link: true,
|
|
330
377
|
icon: EditPen,
|
|
@@ -332,7 +379,7 @@ const columns = computed<ColumnProps[]>(() => [
|
|
|
332
379
|
onClick: scope => handleOpenDialog(undefined, (scope.row as BaseMenu).id)
|
|
333
380
|
},
|
|
334
381
|
{
|
|
335
|
-
label: "
|
|
382
|
+
label: t("common.action.delete"),
|
|
336
383
|
type: "danger",
|
|
337
384
|
link: true,
|
|
338
385
|
icon: Delete,
|
|
@@ -349,14 +396,14 @@ const columns = computed<ColumnProps[]>(() => [
|
|
|
349
396
|
/** 菜单表格顶部按钮配置。 */
|
|
350
397
|
const headerActions = computed<HeaderActionProps[]>(() => [
|
|
351
398
|
{
|
|
352
|
-
label: "
|
|
399
|
+
label: t("common.action.create"),
|
|
353
400
|
type: "success",
|
|
354
401
|
icon: CirclePlus,
|
|
355
402
|
hidden: () => !BUTTONS.value["base:menu:create"],
|
|
356
403
|
onClick: () => handleOpenDialog()
|
|
357
404
|
},
|
|
358
405
|
{
|
|
359
|
-
label: "
|
|
406
|
+
label: t("common.action.delete"),
|
|
360
407
|
type: "danger",
|
|
361
408
|
icon: Delete,
|
|
362
409
|
hidden: () => !BUTTONS.value["base:menu:delete"],
|
|
@@ -378,7 +425,7 @@ const transferData = computed<ProFormOption[]>(() => {
|
|
|
378
425
|
const formFields = computed<ProFormField[]>(() => [
|
|
379
426
|
{
|
|
380
427
|
prop: "parent_id",
|
|
381
|
-
label: "
|
|
428
|
+
label: t("system.base.menu.field.parent"),
|
|
382
429
|
component: "tree-select",
|
|
383
430
|
options: menuOptions.value,
|
|
384
431
|
props: () => ({
|
|
@@ -387,14 +434,14 @@ const formFields = computed<ProFormField[]>(() => [
|
|
|
387
434
|
checkStrictly: true,
|
|
388
435
|
clearable: false,
|
|
389
436
|
filterable: true,
|
|
390
|
-
placeholder: "
|
|
437
|
+
placeholder: t("system.base.menu.placeholder.parent"),
|
|
391
438
|
disabled: dialog.parentLocked,
|
|
392
439
|
style: { width: "100%" }
|
|
393
440
|
})
|
|
394
441
|
},
|
|
395
442
|
{
|
|
396
443
|
prop: "type",
|
|
397
|
-
label: "
|
|
444
|
+
label: t("system.base.menu.field.type"),
|
|
398
445
|
component: "radio-group",
|
|
399
446
|
options: availableMenuTypeOptions.value,
|
|
400
447
|
props: model => ({
|
|
@@ -403,27 +450,40 @@ const formFields = computed<ProFormField[]>(() => [
|
|
|
403
450
|
},
|
|
404
451
|
{
|
|
405
452
|
prop: "meta.title",
|
|
406
|
-
label:
|
|
453
|
+
label: t(
|
|
454
|
+
formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON ? "system.base.menu.field.button_name" : "system.base.menu.field.title"
|
|
455
|
+
),
|
|
407
456
|
component: "input",
|
|
408
457
|
itemProps: {
|
|
409
458
|
required: true
|
|
410
459
|
},
|
|
411
460
|
props: () => ({
|
|
412
|
-
placeholder:
|
|
461
|
+
placeholder: t(
|
|
462
|
+
formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON
|
|
463
|
+
? "system.base.menu.placeholder.button_name"
|
|
464
|
+
: "system.base.menu.placeholder.title"
|
|
465
|
+
)
|
|
413
466
|
})
|
|
414
467
|
},
|
|
468
|
+
{
|
|
469
|
+
prop: "translations",
|
|
470
|
+
label: t("system.base.translation.field.translations"),
|
|
471
|
+
component: "slot",
|
|
472
|
+
slotName: "translations",
|
|
473
|
+
colSpan: 24
|
|
474
|
+
},
|
|
415
475
|
{
|
|
416
476
|
prop: "path",
|
|
417
477
|
label: getPathFieldLabel(),
|
|
418
478
|
component: "input",
|
|
419
479
|
labelTooltip: getPathFieldTooltip(),
|
|
420
480
|
itemProps: model => ({
|
|
421
|
-
required: model.type !== BaseMenuType.
|
|
481
|
+
required: model.type !== BaseMenuType.BASE_MENU_TYPE_FOLDER
|
|
422
482
|
}),
|
|
423
483
|
props: () => ({
|
|
424
484
|
placeholder: getPathFieldPlaceholder()
|
|
425
485
|
}),
|
|
426
|
-
visible: model => model.type !== BaseMenuType.
|
|
486
|
+
visible: model => model.type !== BaseMenuType.BASE_MENU_TYPE_FOLDER
|
|
427
487
|
},
|
|
428
488
|
{
|
|
429
489
|
prop: "redirect",
|
|
@@ -431,184 +491,191 @@ const formFields = computed<ProFormField[]>(() => [
|
|
|
431
491
|
component: "input",
|
|
432
492
|
props: () => ({ placeholder: getRedirectFieldPlaceholder() }),
|
|
433
493
|
itemProps: model => ({
|
|
434
|
-
required: model.type === BaseMenuType.
|
|
494
|
+
required: model.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK
|
|
435
495
|
}),
|
|
436
|
-
visible: model => model.type === BaseMenuType.
|
|
496
|
+
visible: model => model.type === BaseMenuType.BASE_MENU_TYPE_FOLDER || model.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK
|
|
437
497
|
},
|
|
438
498
|
{
|
|
439
499
|
prop: "meta.icon",
|
|
440
|
-
label: "
|
|
500
|
+
label: t("system.base.menu.field.icon"),
|
|
441
501
|
component: "slot",
|
|
442
502
|
slotName: "menuIcon",
|
|
443
503
|
itemProps: model => ({
|
|
444
|
-
required: model.type !== BaseMenuType.
|
|
504
|
+
required: model.type !== BaseMenuType.BASE_MENU_TYPE_BUTTON
|
|
445
505
|
}),
|
|
446
|
-
visible: model => !isAppMenu(model.parent_id) && model.type !== BaseMenuType.
|
|
506
|
+
visible: model => !isAppMenu(model.parent_id) && model.type !== BaseMenuType.BASE_MENU_TYPE_BUTTON
|
|
447
507
|
},
|
|
448
508
|
{
|
|
449
509
|
prop: "meta.icon",
|
|
450
|
-
label: "
|
|
510
|
+
label: t("system.base.menu.field.default_icon"),
|
|
451
511
|
component: "input",
|
|
452
|
-
labelTooltip: "
|
|
512
|
+
labelTooltip: t("system.base.menu.tooltip.mobile_icon"),
|
|
453
513
|
itemProps: model => ({
|
|
454
514
|
required: Boolean(model.meta?.app?.in_tab_bar)
|
|
455
515
|
}),
|
|
456
|
-
props: { placeholder: "
|
|
516
|
+
props: { placeholder: t("system.base.menu.placeholder.default_icon") },
|
|
457
517
|
visible: model => isAppMenu(model.parent_id)
|
|
458
518
|
},
|
|
459
519
|
{
|
|
460
520
|
prop: "name",
|
|
461
|
-
label: isAppMenu(formData.parent_id) ? "
|
|
521
|
+
label: t(isAppMenu(formData.parent_id) ? "system.base.menu.field.logical_name" : "system.base.menu.field.route_name"),
|
|
462
522
|
component: "input",
|
|
463
523
|
labelTooltip: isAppMenu(formData.parent_id)
|
|
464
|
-
? "
|
|
465
|
-
: "
|
|
524
|
+
? t("system.base.menu.tooltip.logical_name")
|
|
525
|
+
: t("system.base.menu.tooltip.route_name"),
|
|
466
526
|
itemProps: model => ({
|
|
467
|
-
required: model.type === BaseMenuType.
|
|
527
|
+
required: model.type === BaseMenuType.BASE_MENU_TYPE_MENU
|
|
468
528
|
}),
|
|
469
529
|
props: () => ({
|
|
470
|
-
placeholder: isAppMenu(formData.parent_id)
|
|
530
|
+
placeholder: isAppMenu(formData.parent_id)
|
|
531
|
+
? t("system.base.menu.placeholder.logical_name")
|
|
532
|
+
: t("system.base.menu.placeholder.route_name")
|
|
471
533
|
}),
|
|
472
|
-
visible: model => model.type === BaseMenuType.
|
|
534
|
+
visible: model => model.type === BaseMenuType.BASE_MENU_TYPE_MENU
|
|
473
535
|
},
|
|
474
536
|
{
|
|
475
537
|
prop: "meta.app.view_key",
|
|
476
|
-
label: "
|
|
538
|
+
label: t("system.base.menu.field.view_key"),
|
|
477
539
|
component: "input",
|
|
478
|
-
labelTooltip: "
|
|
540
|
+
labelTooltip: t("system.base.menu.tooltip.view_key"),
|
|
479
541
|
itemProps: { required: true },
|
|
480
|
-
props: { placeholder: "
|
|
542
|
+
props: { placeholder: t("system.base.menu.placeholder.view_key") },
|
|
481
543
|
visible: model => isAppMenu(model.parent_id)
|
|
482
544
|
},
|
|
483
545
|
{
|
|
484
546
|
prop: "meta.app.access",
|
|
485
|
-
label: "
|
|
547
|
+
label: t("system.base.menu.field.access"),
|
|
486
548
|
component: "select",
|
|
487
|
-
options: appAccessOptions,
|
|
549
|
+
options: appAccessOptions.value,
|
|
488
550
|
itemProps: { required: true },
|
|
489
551
|
props: {
|
|
490
552
|
clearable: false,
|
|
491
|
-
placeholder: "
|
|
553
|
+
placeholder: t("system.base.menu.placeholder.access")
|
|
492
554
|
},
|
|
493
555
|
visible: model => isAppMenu(model.parent_id)
|
|
494
556
|
},
|
|
495
557
|
{
|
|
496
558
|
prop: "meta.app.selected_icon",
|
|
497
|
-
label: "
|
|
559
|
+
label: t("system.base.menu.field.selected_icon"),
|
|
498
560
|
component: "input",
|
|
499
|
-
labelTooltip: "
|
|
561
|
+
labelTooltip: t("system.base.menu.tooltip.mobile_icon"),
|
|
500
562
|
itemProps: { required: true },
|
|
501
|
-
props: { placeholder: "
|
|
563
|
+
props: { placeholder: t("system.base.menu.placeholder.selected_icon") },
|
|
502
564
|
visible: model => isAppTab(model.parent_id)
|
|
503
565
|
},
|
|
504
566
|
{
|
|
505
567
|
prop: "component",
|
|
506
|
-
label: "
|
|
568
|
+
label: t("system.base.menu.field.component"),
|
|
507
569
|
component: "input",
|
|
508
|
-
labelTooltip: "
|
|
570
|
+
labelTooltip: t("system.base.menu.tooltip.component"),
|
|
509
571
|
itemProps: model => ({
|
|
510
|
-
required: model.type === BaseMenuType.
|
|
572
|
+
required: model.type === BaseMenuType.BASE_MENU_TYPE_MENU && !isAppMenu(model.parent_id)
|
|
511
573
|
}),
|
|
512
574
|
props: { placeholder: "system/base/user/index" },
|
|
513
|
-
visible: model => model.type === BaseMenuType.
|
|
575
|
+
visible: model => model.type === BaseMenuType.BASE_MENU_TYPE_MENU && !isAppMenu(model.parent_id)
|
|
514
576
|
},
|
|
515
577
|
{
|
|
516
578
|
prop: "meta.hidden",
|
|
517
|
-
label: "
|
|
579
|
+
label: t("system.base.menu.field.hidden"),
|
|
518
580
|
component: "switch",
|
|
519
581
|
props: {
|
|
520
582
|
inlinePrompt: true,
|
|
521
|
-
activeText: "
|
|
522
|
-
inactiveText: "
|
|
583
|
+
activeText: t("common.value.yes"),
|
|
584
|
+
inactiveText: t("common.value.no"),
|
|
523
585
|
activeValue: true,
|
|
524
586
|
inactiveValue: false
|
|
525
587
|
},
|
|
526
|
-
visible: model => !isAppMenu(model.parent_id) && model.type !== BaseMenuType.
|
|
588
|
+
visible: model => !isAppMenu(model.parent_id) && model.type !== BaseMenuType.BASE_MENU_TYPE_BUTTON
|
|
527
589
|
},
|
|
528
590
|
{
|
|
529
591
|
prop: "meta.always_show",
|
|
530
|
-
label: "
|
|
592
|
+
label: t("system.base.menu.field.always_show"),
|
|
531
593
|
component: "switch",
|
|
532
|
-
labelTooltip: "
|
|
594
|
+
labelTooltip: t("system.base.menu.tooltip.always_show"),
|
|
533
595
|
props: {
|
|
534
596
|
inlinePrompt: true,
|
|
535
|
-
activeText: "
|
|
536
|
-
inactiveText: "
|
|
597
|
+
activeText: t("common.value.yes"),
|
|
598
|
+
inactiveText: t("common.value.no"),
|
|
537
599
|
activeValue: true,
|
|
538
600
|
inactiveValue: false
|
|
539
601
|
},
|
|
540
|
-
visible: model =>
|
|
602
|
+
visible: model =>
|
|
603
|
+
!isAppMenu(model.parent_id) &&
|
|
604
|
+
(model.type === BaseMenuType.BASE_MENU_TYPE_FOLDER || model.type === BaseMenuType.BASE_MENU_TYPE_MENU)
|
|
541
605
|
},
|
|
542
606
|
{
|
|
543
607
|
prop: "meta.keep_alive",
|
|
544
|
-
label: "
|
|
608
|
+
label: t("system.base.menu.field.keep_alive"),
|
|
545
609
|
component: "switch",
|
|
546
610
|
props: {
|
|
547
611
|
inlinePrompt: true,
|
|
548
|
-
activeText: "
|
|
549
|
-
inactiveText: "
|
|
612
|
+
activeText: t("common.status.enabled"),
|
|
613
|
+
inactiveText: t("common.status.disabled"),
|
|
550
614
|
activeValue: true,
|
|
551
615
|
inactiveValue: false
|
|
552
616
|
},
|
|
553
|
-
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.
|
|
617
|
+
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.BASE_MENU_TYPE_MENU
|
|
554
618
|
},
|
|
555
619
|
{
|
|
556
620
|
prop: "meta.full",
|
|
557
|
-
label: "
|
|
621
|
+
label: t("system.base.menu.field.fullscreen"),
|
|
558
622
|
component: "switch",
|
|
559
623
|
props: {
|
|
560
624
|
inlinePrompt: true,
|
|
561
|
-
activeText: "
|
|
562
|
-
inactiveText: "
|
|
625
|
+
activeText: t("common.status.enabled"),
|
|
626
|
+
inactiveText: t("common.status.disabled"),
|
|
563
627
|
activeValue: true,
|
|
564
628
|
inactiveValue: false
|
|
565
629
|
},
|
|
566
|
-
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.
|
|
630
|
+
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.BASE_MENU_TYPE_MENU
|
|
567
631
|
},
|
|
568
632
|
{
|
|
569
633
|
prop: "meta.affix",
|
|
570
|
-
label: "
|
|
634
|
+
label: t("system.base.menu.field.affix"),
|
|
571
635
|
component: "switch",
|
|
572
636
|
props: {
|
|
573
637
|
inlinePrompt: true,
|
|
574
|
-
activeText: "
|
|
575
|
-
inactiveText: "
|
|
638
|
+
activeText: t("common.status.enabled"),
|
|
639
|
+
inactiveText: t("common.status.disabled"),
|
|
576
640
|
activeValue: true,
|
|
577
641
|
inactiveValue: false
|
|
578
642
|
},
|
|
579
|
-
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.
|
|
643
|
+
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.BASE_MENU_TYPE_MENU
|
|
580
644
|
},
|
|
581
645
|
{
|
|
582
646
|
prop: "meta.params",
|
|
583
|
-
label: "
|
|
647
|
+
label: t("system.base.menu.field.route_params"),
|
|
584
648
|
component: "kv-list",
|
|
585
|
-
labelTooltip: "
|
|
649
|
+
labelTooltip: t("system.base.menu.tooltip.route_params"),
|
|
586
650
|
props: {
|
|
587
|
-
addText: "
|
|
588
|
-
keyInputProps: { placeholder: "
|
|
589
|
-
valueInputProps: { placeholder: "
|
|
651
|
+
addText: t("system.base.menu.action.add_route_param"),
|
|
652
|
+
keyInputProps: { placeholder: t("common.field.parameter_name") },
|
|
653
|
+
valueInputProps: { placeholder: t("common.field.parameter_value") }
|
|
590
654
|
},
|
|
591
655
|
itemProps: {
|
|
592
656
|
class: "menu-form__params"
|
|
593
657
|
},
|
|
594
|
-
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.
|
|
658
|
+
visible: model => !isAppMenu(model.parent_id) && model.type === BaseMenuType.BASE_MENU_TYPE_MENU
|
|
595
659
|
},
|
|
596
660
|
{
|
|
597
661
|
prop: "api",
|
|
598
|
-
label: "
|
|
662
|
+
label: t("system.base.menu.field.api_list"),
|
|
599
663
|
component: "transfer",
|
|
600
664
|
slotName: "apiTransferItem",
|
|
601
665
|
options: transferData.value,
|
|
602
666
|
props: {
|
|
603
667
|
filterable: true,
|
|
604
|
-
titles: ["
|
|
668
|
+
titles: [t("system.base.menu.value.available_api"), t("system.base.menu.value.selected_api")]
|
|
605
669
|
},
|
|
606
|
-
visible: model =>
|
|
670
|
+
visible: model =>
|
|
671
|
+
model.id === APP_MENU_ROOT_ID ||
|
|
672
|
+
model.type === BaseMenuType.BASE_MENU_TYPE_MENU ||
|
|
673
|
+
model.type === BaseMenuType.BASE_MENU_TYPE_BUTTON,
|
|
607
674
|
colSpan: 24
|
|
608
675
|
},
|
|
609
676
|
{
|
|
610
677
|
prop: "sort",
|
|
611
|
-
label: "
|
|
678
|
+
label: t("common.field.sort"),
|
|
612
679
|
component: "input-number",
|
|
613
680
|
itemProps: {
|
|
614
681
|
required: true
|
|
@@ -623,23 +690,39 @@ const formFields = computed<ProFormField[]>(() => [
|
|
|
623
690
|
},
|
|
624
691
|
{
|
|
625
692
|
prop: "status",
|
|
626
|
-
label: "
|
|
693
|
+
label: t("common.field.status"),
|
|
627
694
|
component: "radio-group",
|
|
628
695
|
itemProps: {
|
|
629
696
|
required: true
|
|
630
697
|
},
|
|
631
|
-
options: statusOptions
|
|
698
|
+
options: statusOptions.value
|
|
632
699
|
}
|
|
633
700
|
]);
|
|
634
701
|
|
|
635
702
|
const rules = computed<FormRules>(() => ({
|
|
636
|
-
parent_id: formData.id
|
|
637
|
-
|
|
703
|
+
parent_id: formData.id
|
|
704
|
+
? []
|
|
705
|
+
: [{ required: true, type: "number", min: 1, message: t("system.base.menu.placeholder.parent"), trigger: "change" }],
|
|
706
|
+
type: [
|
|
707
|
+
{
|
|
708
|
+
required: true,
|
|
709
|
+
message: t("common.validation.required_select", { field: t("system.base.menu.field.type") }),
|
|
710
|
+
trigger: "change"
|
|
711
|
+
}
|
|
712
|
+
],
|
|
638
713
|
"meta.title": [
|
|
639
714
|
{
|
|
640
715
|
validator: (_rule, value, callback) => {
|
|
641
716
|
if (value) return callback();
|
|
642
|
-
callback(
|
|
717
|
+
callback(
|
|
718
|
+
new Error(
|
|
719
|
+
t(
|
|
720
|
+
formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON
|
|
721
|
+
? "system.base.menu.placeholder.button_name"
|
|
722
|
+
: "system.base.menu.placeholder.title"
|
|
723
|
+
)
|
|
724
|
+
)
|
|
725
|
+
);
|
|
643
726
|
},
|
|
644
727
|
trigger: "blur"
|
|
645
728
|
}
|
|
@@ -647,10 +730,14 @@ const rules = computed<FormRules>(() => ({
|
|
|
647
730
|
"meta.icon": [
|
|
648
731
|
{
|
|
649
732
|
validator: (_rule, value, callback) => {
|
|
650
|
-
if (formData.type === BaseMenuType.
|
|
733
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON) return callback();
|
|
651
734
|
if (isAppMenu(formData.parent_id) && !isAppTab(formData.parent_id)) return callback();
|
|
652
735
|
if (value) return callback();
|
|
653
|
-
callback(
|
|
736
|
+
callback(
|
|
737
|
+
new Error(
|
|
738
|
+
t(isAppMenu(formData.parent_id) ? "system.base.menu.validation.default_icon" : "system.base.menu.placeholder.icon")
|
|
739
|
+
)
|
|
740
|
+
);
|
|
654
741
|
},
|
|
655
742
|
trigger: "change"
|
|
656
743
|
}
|
|
@@ -659,7 +746,7 @@ const rules = computed<FormRules>(() => ({
|
|
|
659
746
|
{
|
|
660
747
|
validator: (_rule, value, callback) => {
|
|
661
748
|
if (!isAppMenu(formData.parent_id) || value) return callback();
|
|
662
|
-
callback(new Error("
|
|
749
|
+
callback(new Error(t("system.base.menu.validation.view_key")));
|
|
663
750
|
},
|
|
664
751
|
trigger: "blur"
|
|
665
752
|
}
|
|
@@ -668,7 +755,7 @@ const rules = computed<FormRules>(() => ({
|
|
|
668
755
|
{
|
|
669
756
|
validator: (_rule, value, callback) => {
|
|
670
757
|
if (!isAppMenu(formData.parent_id) || value) return callback();
|
|
671
|
-
callback(new Error("
|
|
758
|
+
callback(new Error(t("system.base.menu.placeholder.access")));
|
|
672
759
|
},
|
|
673
760
|
trigger: "change"
|
|
674
761
|
}
|
|
@@ -677,23 +764,37 @@ const rules = computed<FormRules>(() => ({
|
|
|
677
764
|
{
|
|
678
765
|
validator: (_rule, value, callback) => {
|
|
679
766
|
if (!isAppTab(formData.parent_id) || value) return callback();
|
|
680
|
-
callback(new Error("
|
|
767
|
+
callback(new Error(t("system.base.menu.validation.selected_icon")));
|
|
681
768
|
},
|
|
682
769
|
trigger: "blur"
|
|
683
770
|
}
|
|
684
771
|
],
|
|
685
772
|
path: [
|
|
686
|
-
{
|
|
773
|
+
{
|
|
774
|
+
max: 1024,
|
|
775
|
+
message: t("common.validation.max_length", { field: t("system.base.menu.field.path"), max: 1024 }),
|
|
776
|
+
trigger: "blur"
|
|
777
|
+
},
|
|
687
778
|
{
|
|
688
779
|
validator: (_rule, value, callback) => {
|
|
689
|
-
if (formData.type === BaseMenuType.
|
|
780
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_FOLDER) return callback();
|
|
690
781
|
if (!value) {
|
|
691
|
-
if (formData.type === BaseMenuType.
|
|
692
|
-
|
|
693
|
-
|
|
782
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON)
|
|
783
|
+
return callback(new Error(t("system.base.menu.validation.permission")));
|
|
784
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK)
|
|
785
|
+
return callback(new Error(t("system.base.menu.validation.external_url")));
|
|
786
|
+
return callback(
|
|
787
|
+
new Error(
|
|
788
|
+
t(
|
|
789
|
+
isAppMenu(formData.parent_id)
|
|
790
|
+
? "system.base.menu.validation.logical_path"
|
|
791
|
+
: "system.base.menu.validation.route_path"
|
|
792
|
+
)
|
|
793
|
+
)
|
|
794
|
+
);
|
|
694
795
|
}
|
|
695
796
|
if (isAppMenu(formData.parent_id) && !String(value).startsWith("app/")) {
|
|
696
|
-
return callback(new Error("
|
|
797
|
+
return callback(new Error(t("system.base.menu.validation.app_path_prefix")));
|
|
697
798
|
}
|
|
698
799
|
callback();
|
|
699
800
|
},
|
|
@@ -701,24 +802,41 @@ const rules = computed<FormRules>(() => ({
|
|
|
701
802
|
}
|
|
702
803
|
],
|
|
703
804
|
redirect: [
|
|
704
|
-
{
|
|
805
|
+
{
|
|
806
|
+
max: 1024,
|
|
807
|
+
message: t("common.validation.max_length", { field: t("system.base.menu.field.redirect"), max: 1024 }),
|
|
808
|
+
trigger: "blur"
|
|
809
|
+
},
|
|
705
810
|
{
|
|
706
811
|
validator: (_rule, value, callback) => {
|
|
707
|
-
if (formData.type !== BaseMenuType.
|
|
812
|
+
if (formData.type !== BaseMenuType.BASE_MENU_TYPE_EXT_LINK) return callback();
|
|
708
813
|
if (/^https?:\/\/\S+$/.test(value)) return callback();
|
|
709
|
-
callback(new Error("
|
|
814
|
+
callback(new Error(t("system.base.menu.validation.http_url")));
|
|
710
815
|
},
|
|
711
816
|
trigger: "blur"
|
|
712
817
|
}
|
|
713
818
|
],
|
|
714
819
|
name: [
|
|
715
|
-
{
|
|
820
|
+
{
|
|
821
|
+
max: 255,
|
|
822
|
+
message: t("common.validation.max_length", { field: t("system.base.menu.field.route_name"), max: 255 }),
|
|
823
|
+
trigger: "blur"
|
|
824
|
+
},
|
|
716
825
|
{
|
|
717
826
|
validator: (_rule, value, callback) => {
|
|
718
|
-
if (formData.type !== BaseMenuType.
|
|
719
|
-
if (!value)
|
|
827
|
+
if (formData.type !== BaseMenuType.BASE_MENU_TYPE_MENU) return callback();
|
|
828
|
+
if (!value)
|
|
829
|
+
return callback(
|
|
830
|
+
new Error(
|
|
831
|
+
t(
|
|
832
|
+
isAppMenu(formData.parent_id)
|
|
833
|
+
? "system.base.menu.validation.logical_name"
|
|
834
|
+
: "system.base.menu.placeholder.route_name"
|
|
835
|
+
)
|
|
836
|
+
)
|
|
837
|
+
);
|
|
720
838
|
if (isAppMenu(formData.parent_id) && !String(value).startsWith("App")) {
|
|
721
|
-
return callback(new Error("
|
|
839
|
+
return callback(new Error(t("system.base.menu.validation.app_name_prefix")));
|
|
722
840
|
}
|
|
723
841
|
callback();
|
|
724
842
|
},
|
|
@@ -726,54 +844,70 @@ const rules = computed<FormRules>(() => ({
|
|
|
726
844
|
}
|
|
727
845
|
],
|
|
728
846
|
component: [
|
|
729
|
-
{
|
|
847
|
+
{
|
|
848
|
+
max: 255,
|
|
849
|
+
message: t("common.validation.max_length", { field: t("system.base.menu.field.component"), max: 255 }),
|
|
850
|
+
trigger: "blur"
|
|
851
|
+
},
|
|
730
852
|
{
|
|
731
853
|
validator: (_rule, value, callback) => {
|
|
732
|
-
if (formData.type !== BaseMenuType.
|
|
854
|
+
if (formData.type !== BaseMenuType.BASE_MENU_TYPE_MENU || isAppMenu(formData.parent_id)) return callback();
|
|
733
855
|
if (value) return callback();
|
|
734
|
-
callback(new Error("
|
|
856
|
+
callback(new Error(t("system.base.menu.validation.component")));
|
|
735
857
|
},
|
|
736
858
|
trigger: "blur"
|
|
737
859
|
}
|
|
738
860
|
],
|
|
739
|
-
sort: [{ required: true, type: "number", min: 1, message: "
|
|
740
|
-
status: [
|
|
861
|
+
sort: [{ required: true, type: "number", min: 1, message: t("common.validation.sort_positive"), trigger: "blur" }],
|
|
862
|
+
status: [
|
|
863
|
+
{
|
|
864
|
+
required: true,
|
|
865
|
+
message: t("common.validation.required_select", { field: t("common.field.status") }),
|
|
866
|
+
trigger: "change"
|
|
867
|
+
}
|
|
868
|
+
]
|
|
741
869
|
}));
|
|
742
870
|
|
|
743
871
|
/** 计算当前路径字段文案。 */
|
|
744
872
|
function getPathFieldLabel() {
|
|
745
|
-
if (isAppMenu(formData.parent_id)) return "
|
|
746
|
-
if (formData.type === BaseMenuType.
|
|
747
|
-
if (formData.type === BaseMenuType.
|
|
748
|
-
return "
|
|
873
|
+
if (isAppMenu(formData.parent_id)) return t("system.base.menu.field.logical_path");
|
|
874
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON) return t("system.base.menu.field.permission");
|
|
875
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK) return t("system.base.menu.field.internal_path");
|
|
876
|
+
return t("system.base.menu.field.path");
|
|
749
877
|
}
|
|
750
878
|
|
|
751
879
|
/** 计算当前路径字段占位文案。 */
|
|
752
880
|
function getPathFieldPlaceholder() {
|
|
753
|
-
if (isAppMenu(formData.parent_id)) return "
|
|
754
|
-
if (formData.type === BaseMenuType.
|
|
755
|
-
if (formData.type === BaseMenuType.
|
|
756
|
-
if (formData.type === BaseMenuType.
|
|
881
|
+
if (isAppMenu(formData.parent_id)) return t("system.base.menu.placeholder.logical_path");
|
|
882
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON) return t("system.base.menu.placeholder.permission");
|
|
883
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK) return "external/baidu";
|
|
884
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_FOLDER) return "base";
|
|
757
885
|
return "user";
|
|
758
886
|
}
|
|
759
887
|
|
|
760
888
|
/** 计算当前路径字段提示文案。 */
|
|
761
889
|
function getPathFieldTooltip() {
|
|
762
|
-
if (isAppMenu(formData.parent_id)) return "
|
|
763
|
-
if (formData.type === BaseMenuType.
|
|
764
|
-
if (formData.type === BaseMenuType.
|
|
765
|
-
if (formData.type === BaseMenuType.
|
|
766
|
-
return "
|
|
890
|
+
if (isAppMenu(formData.parent_id)) return t("system.base.menu.tooltip.logical_path");
|
|
891
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_BUTTON) return t("system.base.menu.tooltip.permission");
|
|
892
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK) return t("system.base.menu.tooltip.internal_path");
|
|
893
|
+
if (formData.type === BaseMenuType.BASE_MENU_TYPE_FOLDER) return t("system.base.menu.tooltip.folder_path");
|
|
894
|
+
return t("system.base.menu.tooltip.route_path");
|
|
767
895
|
}
|
|
768
896
|
|
|
769
897
|
/** 计算重定向字段文案。 */
|
|
770
898
|
function getRedirectFieldLabel() {
|
|
771
|
-
return
|
|
899
|
+
return t(
|
|
900
|
+
formData.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK
|
|
901
|
+
? "system.base.menu.field.external_url"
|
|
902
|
+
: "system.base.menu.field.redirect_route"
|
|
903
|
+
);
|
|
772
904
|
}
|
|
773
905
|
|
|
774
906
|
/** 计算重定向字段占位文案。 */
|
|
775
907
|
function getRedirectFieldPlaceholder() {
|
|
776
|
-
return formData.type === BaseMenuType.
|
|
908
|
+
return formData.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK
|
|
909
|
+
? "https://www.example.com/"
|
|
910
|
+
: t("system.base.menu.placeholder.redirect_route");
|
|
777
911
|
}
|
|
778
912
|
|
|
779
913
|
/** 判断当前图标是否为 Element Plus 图标。 */
|
|
@@ -830,7 +964,7 @@ function normalizeMenuForm(data?: Partial<BaseMenuForm>): MenuFormState {
|
|
|
830
964
|
...defaultForm,
|
|
831
965
|
...data,
|
|
832
966
|
parent_id: parentId,
|
|
833
|
-
type: data?.type ?? BaseMenuType.
|
|
967
|
+
type: data?.type ?? BaseMenuType.BASE_MENU_TYPE_FOLDER,
|
|
834
968
|
status: data?.status ?? Status.ENABLE,
|
|
835
969
|
api: normalizeMenuApiSelection(data?.api),
|
|
836
970
|
sort: data?.sort ?? 1,
|
|
@@ -844,7 +978,7 @@ function buildMenuOptions(menuList: BaseMenu[] = []) {
|
|
|
844
978
|
const mobileIds = new Set<number>([APP_MENU_ROOT_ID]);
|
|
845
979
|
const convert = (list: BaseMenu[]): ProFormOption[] =>
|
|
846
980
|
list
|
|
847
|
-
.filter(item => item.type === BaseMenuType.
|
|
981
|
+
.filter(item => item.type === BaseMenuType.BASE_MENU_TYPE_FOLDER || item.type === BaseMenuType.BASE_MENU_TYPE_MENU)
|
|
848
982
|
.map(item => {
|
|
849
983
|
typeMap.set(item.id, item.type);
|
|
850
984
|
if (mobileIds.has(item.parent_id ?? 0)) mobileIds.add(item.id);
|
|
@@ -863,6 +997,11 @@ function buildMenuOptions(menuList: BaseMenu[] = []) {
|
|
|
863
997
|
/** 根据菜单类型清理无效字段,避免提交脏数据。 */
|
|
864
998
|
function buildSubmitPayload(): BaseMenuForm {
|
|
865
999
|
const payload = normalizeMenuForm(formData);
|
|
1000
|
+
payload.translations = serializeDynamicTranslations(
|
|
1001
|
+
translationValues.value,
|
|
1002
|
+
TranslationTargetType.TRANSLATION_TARGET_TYPE_BASE_MENU,
|
|
1003
|
+
payload.id
|
|
1004
|
+
);
|
|
866
1005
|
// 一级菜单在表单中保持空白,提交时仍按接口约定传回根节点标识。
|
|
867
1006
|
if (payload.id > 0 && payload.parent_id === undefined) payload.parent_id = 0;
|
|
868
1007
|
payload.meta.params = (payload.meta.params ?? []).filter(item => item.key || item.value);
|
|
@@ -881,7 +1020,7 @@ function buildSubmitPayload(): BaseMenuForm {
|
|
|
881
1020
|
if (!payload.meta.app.in_tab_bar) payload.meta.app.selected_icon = undefined;
|
|
882
1021
|
}
|
|
883
1022
|
|
|
884
|
-
if (payload.type === BaseMenuType.
|
|
1023
|
+
if (payload.type === BaseMenuType.BASE_MENU_TYPE_BUTTON) {
|
|
885
1024
|
payload.name = "";
|
|
886
1025
|
payload.component = "";
|
|
887
1026
|
payload.redirect = "";
|
|
@@ -894,7 +1033,7 @@ function buildSubmitPayload(): BaseMenuForm {
|
|
|
894
1033
|
payload.meta.params = [];
|
|
895
1034
|
}
|
|
896
1035
|
|
|
897
|
-
if (payload.type === BaseMenuType.
|
|
1036
|
+
if (payload.type === BaseMenuType.BASE_MENU_TYPE_FOLDER) {
|
|
898
1037
|
payload.path = "";
|
|
899
1038
|
payload.name = "";
|
|
900
1039
|
payload.component = "Layout";
|
|
@@ -905,7 +1044,7 @@ function buildSubmitPayload(): BaseMenuForm {
|
|
|
905
1044
|
payload.meta.params = [];
|
|
906
1045
|
}
|
|
907
1046
|
|
|
908
|
-
if (payload.type === BaseMenuType.
|
|
1047
|
+
if (payload.type === BaseMenuType.BASE_MENU_TYPE_EXT_LINK) {
|
|
909
1048
|
payload.name = "";
|
|
910
1049
|
payload.component = "";
|
|
911
1050
|
payload.api = [];
|
|
@@ -953,6 +1092,7 @@ function filterMenuTree(menuList: BaseMenu[], keywordMap: Record<string, string>
|
|
|
953
1092
|
|
|
954
1093
|
/** 请求菜单表格数据,并按搜索条件过滤树形结构。 */
|
|
955
1094
|
async function requestMenuTable(params: Record<string, string>) {
|
|
1095
|
+
await loadEnabledBaseLanguages();
|
|
956
1096
|
const data = await defBaseMenuService.TreeBaseMenu({});
|
|
957
1097
|
const keywordMap = {
|
|
958
1098
|
title: params.title ?? "",
|
|
@@ -975,26 +1115,25 @@ function refreshTable() {
|
|
|
975
1115
|
* parentMenu 为新增时的固定父节点,menuId 为编辑时的菜单 ID。
|
|
976
1116
|
*/
|
|
977
1117
|
async function handleOpenDialog(parentMenu?: BaseMenu, menuId?: number) {
|
|
1118
|
+
await loadEnabledBaseLanguages();
|
|
978
1119
|
await loadDialogResources();
|
|
979
1120
|
dialog.parentLocked = Boolean(parentMenu || menuId);
|
|
980
|
-
dialog.
|
|
1121
|
+
dialog.editing = Boolean(menuId);
|
|
1122
|
+
dialog.parentType = parentMenu?.type ?? BaseMenuType.BASE_MENU_TYPE_UNSPECIFIED;
|
|
981
1123
|
resetForm(menuId ? undefined : { parent_id: parentMenu?.id });
|
|
982
1124
|
dialog.visible = true;
|
|
983
1125
|
|
|
984
1126
|
if (menuId) {
|
|
985
|
-
dialog.title = "修改菜单";
|
|
986
1127
|
const data = await defBaseMenuService.GetBaseMenu({ id: menuId });
|
|
987
1128
|
resetForm(data);
|
|
988
1129
|
return;
|
|
989
1130
|
}
|
|
990
|
-
|
|
991
|
-
dialog.title = "新增菜单";
|
|
992
1131
|
}
|
|
993
1132
|
|
|
994
1133
|
/** 关闭菜单弹窗并显式重置表单与校验状态。 */
|
|
995
1134
|
function handleCloseDialog() {
|
|
996
1135
|
dialog.visible = false;
|
|
997
|
-
dialog.parentType = BaseMenuType.
|
|
1136
|
+
dialog.parentType = BaseMenuType.BASE_MENU_TYPE_UNSPECIFIED;
|
|
998
1137
|
dialog.parentLocked = true;
|
|
999
1138
|
resetForm();
|
|
1000
1139
|
}
|
|
@@ -1004,6 +1143,7 @@ function resetForm(data?: Partial<BaseMenuForm>) {
|
|
|
1004
1143
|
formDialogRef.value?.resetFields();
|
|
1005
1144
|
formDialogRef.value?.clearValidate();
|
|
1006
1145
|
Object.assign(formData, normalizeMenuForm(data));
|
|
1146
|
+
translationValues.value = normalizeDynamicTranslations(data?.translations as DynamicTranslationRecord[] | undefined, "title");
|
|
1007
1147
|
}
|
|
1008
1148
|
|
|
1009
1149
|
/** 提交菜单表单,并在成功后关闭弹窗、刷新表格。 */
|
|
@@ -1014,10 +1154,10 @@ async function handleSubmit() {
|
|
|
1014
1154
|
const payload = buildSubmitPayload();
|
|
1015
1155
|
if (payload.id > 0) {
|
|
1016
1156
|
await defBaseMenuService.UpdateBaseMenu({ base_menu: payload });
|
|
1017
|
-
ElMessage.success("
|
|
1157
|
+
ElMessage.success(t("system.base.menu.message.update_success"));
|
|
1018
1158
|
} else {
|
|
1019
1159
|
await defBaseMenuService.CreateBaseMenu({ base_menu: payload });
|
|
1020
|
-
ElMessage.success("
|
|
1160
|
+
ElMessage.success(t("system.base.menu.message.create_success"));
|
|
1021
1161
|
}
|
|
1022
1162
|
|
|
1023
1163
|
handleCloseDialog();
|
|
@@ -1029,16 +1169,20 @@ async function handleSubmit() {
|
|
|
1029
1169
|
*/
|
|
1030
1170
|
async function handleBeforeSetStatus(row: BaseMenu) {
|
|
1031
1171
|
const nextStatus = row.status === Status.ENABLE ? Status.DISABLE : Status.ENABLE;
|
|
1032
|
-
const
|
|
1172
|
+
const action = t(nextStatus === Status.ENABLE ? "common.status.enabled" : "common.status.disabled");
|
|
1033
1173
|
const menuName = row.meta?.title || row.name || row.path || `ID:${row.id}`;
|
|
1034
1174
|
try {
|
|
1035
|
-
await ElMessageBox.confirm(
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1175
|
+
await ElMessageBox.confirm(
|
|
1176
|
+
t("system.base.menu.message.confirm_status", { action, name: menuName }),
|
|
1177
|
+
t("common.title.notice"),
|
|
1178
|
+
{
|
|
1179
|
+
confirmButtonText: t("common.action.confirm"),
|
|
1180
|
+
cancelButtonText: t("common.action.cancel"),
|
|
1181
|
+
type: "warning"
|
|
1182
|
+
}
|
|
1183
|
+
);
|
|
1040
1184
|
await defBaseMenuService.SetBaseMenuStatus({ id: row.id, status: nextStatus });
|
|
1041
|
-
ElMessage.success(
|
|
1185
|
+
ElMessage.success(t("common.message.status_success", { action }));
|
|
1042
1186
|
refreshTable();
|
|
1043
1187
|
return true;
|
|
1044
1188
|
} catch {
|
|
@@ -1056,37 +1200,37 @@ function handleDeleteMenu(selected?: number | string | Array<number | string> |
|
|
|
1056
1200
|
? [selected as BaseMenu]
|
|
1057
1201
|
: [];
|
|
1058
1202
|
if (menuList.some(item => item.parent_id === 0 || item.id === APP_MENU_ROOT_ID)) {
|
|
1059
|
-
ElMessage.warning("
|
|
1203
|
+
ElMessage.warning(t("system.base.menu.message.protected_delete"));
|
|
1060
1204
|
return;
|
|
1061
1205
|
}
|
|
1062
1206
|
const menuIds = (
|
|
1063
1207
|
menuList.length ? menuList.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>)
|
|
1064
1208
|
).join(",");
|
|
1065
1209
|
if (!menuIds) {
|
|
1066
|
-
ElMessage.warning("
|
|
1210
|
+
ElMessage.warning(t("common.message.select_delete_item"));
|
|
1067
1211
|
return;
|
|
1068
1212
|
}
|
|
1069
1213
|
|
|
1070
1214
|
const singleMenuName = menuList[0]?.meta?.title || menuList[0]?.name || menuList[0]?.path || `ID:${menuList[0]?.id ?? ""}`;
|
|
1071
1215
|
const confirmMessage = menuList.length
|
|
1072
1216
|
? menuList.length === 1
|
|
1073
|
-
?
|
|
1074
|
-
:
|
|
1075
|
-
: "
|
|
1217
|
+
? t("system.base.menu.message.confirm_delete_single", { name: singleMenuName })
|
|
1218
|
+
: t("system.base.menu.message.confirm_delete_batch", { count: menuList.length })
|
|
1219
|
+
: t("system.base.menu.message.confirm_delete_selected");
|
|
1076
1220
|
|
|
1077
|
-
ElMessageBox.confirm(confirmMessage, "
|
|
1078
|
-
confirmButtonText: "
|
|
1079
|
-
cancelButtonText: "
|
|
1221
|
+
ElMessageBox.confirm(confirmMessage, t("common.title.warning"), {
|
|
1222
|
+
confirmButtonText: t("common.action.confirm"),
|
|
1223
|
+
cancelButtonText: t("common.action.cancel"),
|
|
1080
1224
|
type: "warning"
|
|
1081
1225
|
}).then(
|
|
1082
1226
|
() => {
|
|
1083
1227
|
defBaseMenuService.DeleteBaseMenu({ id: menuIds }).then(() => {
|
|
1084
|
-
ElMessage.success("
|
|
1228
|
+
ElMessage.success(t("system.base.menu.message.delete_success"));
|
|
1085
1229
|
refreshTable();
|
|
1086
1230
|
});
|
|
1087
1231
|
},
|
|
1088
1232
|
() => {
|
|
1089
|
-
ElMessage.info("
|
|
1233
|
+
ElMessage.info(t("system.base.menu.message.delete_canceled"));
|
|
1090
1234
|
}
|
|
1091
1235
|
);
|
|
1092
1236
|
}
|