This commit is contained in:
xingyu4j
2026-01-04 10:56:14 +08:00
18 changed files with 1029 additions and 837 deletions

View File

@@ -94,4 +94,32 @@ function mapTree<T, V extends Record<string, any>>(
});
}
export { filterTree, mapTree, traverseTreeValues };
/**
* 对树形结构数据进行递归排序
* @param treeData - 树形数据数组
* @param sortFunction - 排序函数,用于定义排序规则
* @param options - 配置选项,包括子节点属性名
* @returns 排序后的树形数据
*/
function sortTree<T extends Record<string, any>>(
treeData: T[],
sortFunction: (a: T, b: T) => number,
options?: TreeConfigOptions,
): T[] {
const { childProps } = options || {
childProps: 'children',
};
return treeData.toSorted(sortFunction).map((item) => {
const children = item[childProps];
if (children && Array.isArray(children) && children.length > 0) {
return {
...item,
[childProps]: sortTree(children, sortFunction, options),
};
}
return item;
});
}
export { filterTree, mapTree, sortTree, traverseTreeValues };

View File

@@ -73,6 +73,7 @@ function handleClick(menu: IContextMenuItem) {
>
<template v-for="menu in menusView" :key="menu.key">
<ContextMenuItem
v-if="!menu.hidden"
:class="itemClass"
:disabled="menu.disabled"
:inset="menu.inset || !menu.icon"

View File

@@ -10,6 +10,10 @@ interface IContextMenuItem {
* @param data
*/
handler?: (data: any) => void;
/**
* @zh_CN 是否隐藏
*/
hidden?: boolean;
/**
* @zh_CN 图标
*/

View File

@@ -27,7 +27,7 @@ function handleItemClick(value: string) {
</DropdownMenuTrigger>
<DropdownMenuContent align="start">
<DropdownMenuGroup>
<template v-for="(menu, index) in menus" :key="index">
<template v-for="menu in menus" :key="menu.value">
<DropdownMenuItem
:class="
menu.value === modelValue

View File

@@ -20,6 +20,7 @@ export {
VbenButtonGroup,
VbenCheckbox,
VbenCheckButtonGroup,
VbenContextMenu,
VbenCountToAnimator,
VbenFullScreen,
VbenInputPassword,

View File

@@ -7,7 +7,9 @@
"length": "{0} must be {1} characters long",
"alreadyExists": "{0} `{1}` already exists",
"startWith": "{0} must start with `{1}`",
"invalidURL": "Please input a valid URL"
"invalidURL": "Please input a valid URL",
"sizeLimit": "The file size cannot exceed {0}MB",
"previewWarning": "Unable to open the file, there is no available URL or preview address"
},
"actionTitle": {
"edit": "Modify {0}",
@@ -25,7 +27,7 @@
"placeholder": {
"input": "Please enter",
"select": "Please select",
"upload": "Please upload"
"upload": "Click to upload"
},
"captcha": {
"title": "Please complete the security verification",

View File

@@ -7,7 +7,9 @@
"length": "{0}长度必须为{1}个字符",
"alreadyExists": "{0} `{1}` 已存在",
"startWith": "{0}必须以 {1} 开头",
"invalidURL": "请输入有效的链接"
"invalidURL": "请输入有效的链接",
"sizeLimit": "文件大小不能超过 {0}MB",
"previewWarning": "无法打开文件没有可用的URL或预览地址"
},
"actionTitle": {
"edit": "修改{0}",
@@ -25,7 +27,7 @@
"placeholder": {
"input": "请输入",
"select": "请选择",
"upload": "上传"
"upload": "点击上传"
},
"captcha": {
"title": "请完成安全验证",

View File

@@ -6,7 +6,7 @@ import type {
RouteMeta,
} from '@vben-core/typings';
import { filterTree, mapTree } from '@vben-core/shared/utils';
import { filterTree, mapTree, sortTree } from '@vben-core/shared/utils';
/**
* 根据 routes 生成菜单列表
@@ -81,7 +81,7 @@ function generateMenus(
});
// 对菜单进行排序避免order=0时被替换成999的问题
menus = menus.toSorted((a, b) => (a?.order ?? 999) - (b?.order ?? 999));
menus = sortTree(menus, (a, b) => (a?.order ?? 999) - (b?.order ?? 999));
// 过滤掉隐藏的菜单项
return filterTree(menus, (menu) => !!menu.show);