From ccf70a1b762e1d77916c3d580fda8295b7fe98a4 Mon Sep 17 00:00:00 2001 From: xueyitt <1455668754@qq.com> Date: Mon, 22 Dec 2025 19:57:21 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20=E4=BF=AE=E6=AD=A3=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E6=8E=92=E5=BA=8F=E5=9C=A8=E4=BA=8C=E7=BA=A7=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E4=B8=8D=E7=94=9F=E6=95=88=E9=97=AE=E9=A2=98=20(#7007?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * treeUtil增加对树形结构数据进行递归排序 * 菜单sort排序各级菜单均生效 --- packages/@core/base/shared/src/utils/tree.ts | 30 +++++++++++++++++++- packages/utils/src/helpers/generate-menus.ts | 4 +-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/@core/base/shared/src/utils/tree.ts b/packages/@core/base/shared/src/utils/tree.ts index 09a9481cb..f3056dcf5 100644 --- a/packages/@core/base/shared/src/utils/tree.ts +++ b/packages/@core/base/shared/src/utils/tree.ts @@ -94,4 +94,32 @@ function mapTree>( }); } -export { filterTree, mapTree, traverseTreeValues }; +/** + * 对树形结构数据进行递归排序 + * @param treeData - 树形数据数组 + * @param sortFunction - 排序函数,用于定义排序规则 + * @param options - 配置选项,包括子节点属性名 + * @returns 排序后的树形数据 + */ +function sortTree>( + 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 }; diff --git a/packages/utils/src/helpers/generate-menus.ts b/packages/utils/src/helpers/generate-menus.ts index af36bd70c..f13d599ac 100644 --- a/packages/utils/src/helpers/generate-menus.ts +++ b/packages/utils/src/helpers/generate-menus.ts @@ -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); From 022d538940b80c835c2c023e7aad84e41d7292b3 Mon Sep 17 00:00:00 2001 From: zhenghaoyang24 <95458562+zhenghaoyang24@users.noreply.github.com> Date: Mon, 22 Dec 2025 19:58:05 +0800 Subject: [PATCH 2/6] Fix formatting in thin.md for clarity (#7008) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改一些语句错误 --- docs/src/guide/introduction/thin.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/guide/introduction/thin.md b/docs/src/guide/introduction/thin.md index 157d51ffc..8a37c2578 100644 --- a/docs/src/guide/introduction/thin.md +++ b/docs/src/guide/introduction/thin.md @@ -24,7 +24,7 @@ apps/web-naive ## 演示代码精简 -如果你不需要演示代码,你可以直接删除的`playground`文件夹。 +如果你不需要演示代码,你可以直接删除 `playground` 文件夹。 ## 文档精简 @@ -88,7 +88,7 @@ pnpm install - 在应用的 `src/router/routes` 文件中,你可以删除不需要的路由。其中 `core` 文件夹内,如果只需要登录和忘记密码,你可以删除其他路由,如忘记密码、注册等。路由删除后,你可以删除对应的页面文件,在 `src/views/_core` 文件夹中。 -- 在应用的 `src/router/routes` 文件中,你可以按需求删除不需要的路由,如`demos`、`vben` 目录等。路由删除后,你可以删除对应的页面文件,在 `src/views` 文件夹中。 +- 在应用的 `src/router/routes` 文件中,你可以按需求删除不需要的路由,如`demos`、`vben` 目录等。路由删除后,你可以在 `src/views` 文件夹中删除对应的页面文件。 ### 删除不需要的组件 From a1bb13223380540394afdf2bb62ca5a3e966cff1 Mon Sep 17 00:00:00 2001 From: JyQAQ <45193678+jyqwq@users.noreply.github.com> Date: Mon, 22 Dec 2025 20:00:31 +0800 Subject: [PATCH 3/6] =?UTF-8?q?feat(api-cascader):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E8=81=94=E7=BA=A7=E7=BB=84=E4=BB=B6ApiCascader=20(#7031)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/adapter/component/index.ts | 13 +++++++++++++ playground/src/adapter/component/index.ts | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/apps/web-antd/src/adapter/component/index.ts b/apps/web-antd/src/adapter/component/index.ts index 8455ef3aa..1d288009e 100644 --- a/apps/web-antd/src/adapter/component/index.ts +++ b/apps/web-antd/src/adapter/component/index.ts @@ -75,6 +75,9 @@ const TimePicker = defineAsyncComponent( const TreeSelect = defineAsyncComponent( () => import('ant-design-vue/es/tree-select'), ); +const Cascader = defineAsyncComponent( + () => import('ant-design-vue/es/cascader'), +); const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); const Image = defineAsyncComponent(() => import('ant-design-vue/es/image')); const PreviewGroup = defineAsyncComponent(() => @@ -327,9 +330,11 @@ const previewImage = async ( // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 export type ComponentType = + | 'ApiCascader' | 'ApiSelect' | 'ApiTreeSelect' | 'AutoComplete' + | 'Cascader' | 'Checkbox' | 'CheckboxGroup' | 'DatePicker' @@ -359,6 +364,13 @@ async function initComponentAdapter() { // 如果你的组件体积比较大,可以使用异步加载 // Button: () => // import('xxx').then((res) => res.Button), + ApiCascader: withDefaultPlaceholder(ApiComponent, 'select', { + component: Cascader, + fieldNames: { label: 'label', value: 'value', children: 'children' }, + loadingSlot: 'suffixIcon', + modelPropName: 'value', + visibleEvent: 'onVisibleChange', + }), ApiSelect: withDefaultPlaceholder( { ...ApiComponent, @@ -388,6 +400,7 @@ async function initComponentAdapter() { }, ), AutoComplete, + Cascader, Checkbox, CheckboxGroup, DatePicker, diff --git a/playground/src/adapter/component/index.ts b/playground/src/adapter/component/index.ts index 2e50f6dae..261a7d3be 100644 --- a/playground/src/adapter/component/index.ts +++ b/playground/src/adapter/component/index.ts @@ -75,6 +75,9 @@ const TimePicker = defineAsyncComponent( const TreeSelect = defineAsyncComponent( () => import('ant-design-vue/es/tree-select'), ); +const Cascader = defineAsyncComponent( + () => import('ant-design-vue/es/cascader'), +); const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload')); const Image = defineAsyncComponent(() => import('ant-design-vue/es/image')); const PreviewGroup = defineAsyncComponent(() => @@ -336,9 +339,11 @@ const previewImage = async ( // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 export type ComponentType = + | 'ApiCascader' | 'ApiSelect' | 'ApiTreeSelect' | 'AutoComplete' + | 'Cascader' | 'Checkbox' | 'CheckboxGroup' | 'DatePicker' @@ -369,6 +374,13 @@ async function initComponentAdapter() { // Button: () => // import('xxx').then((res) => res.Button), + ApiCascader: withDefaultPlaceholder(ApiComponent, 'select', { + component: Cascader, + fieldNames: { label: 'label', value: 'value', children: 'children' }, + loadingSlot: 'suffixIcon', + modelPropName: 'value', + visibleEvent: 'onVisibleChange', + }), ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', { component: Select, loadingSlot: 'suffixIcon', @@ -384,6 +396,7 @@ async function initComponentAdapter() { visibleEvent: 'onVisibleChange', }), AutoComplete, + Cascader, Checkbox, CheckboxGroup, DatePicker, From 89b237f6b42d5b98ca0dcb3b9bfb5583122575c0 Mon Sep 17 00:00:00 2001 From: luoqiz Date: Fri, 2 Jan 2026 14:22:19 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E4=B8=8A?= =?UTF-8?q?=E4=B8=8B=E6=96=87=E8=8F=9C=E5=8D=95=E6=BC=94=E7=A4=BA=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E8=8F=9C=E5=8D=95=E9=A1=B9=E9=9A=90=E8=97=8F?= =?UTF-8?q?=E6=80=A7=20(#7057)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: luoqiz <851092732@qq.com> --- .../components/context-menu/context-menu.vue | 1 + .../src/components/context-menu/interface.ts | 4 + .../effects/common-ui/src/components/index.ts | 1 + playground/package.json | 1 + .../src/locales/langs/en-US/examples.json | 3 + .../src/locales/langs/zh-CN/examples.json | 3 + .../src/router/routes/modules/examples.ts | 9 + .../src/views/examples/context-menu/index.vue | 60 + pnpm-lock.yaml | 4151 +++++++++-------- 9 files changed, 2228 insertions(+), 2005 deletions(-) create mode 100644 playground/src/views/examples/context-menu/index.vue diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue b/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue index 4b7a64cbb..009f267ef 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/components/context-menu/context-menu.vue @@ -73,6 +73,7 @@ function handleClick(menu: IContextMenuItem) { >