Parcourir la source

Merge branch 'fork/xingyu4j/antdv-next'

Jin Mao il y a 3 semaines
Parent
commit
76cfcda2e9
100 fichiers modifiés avec 524 ajouts et 240 suppressions
  1. 0 5
      .changeset/element-plus-theme-switch.md
  2. 0 5
      .changeset/page-auto-content-height.md
  3. 0 5
      .changeset/small-moons-hunt.md
  4. 0 5
      .changeset/tree-default-value.md
  5. 0 12
      .npmrc
  6. 1 1
      .vscode/settings.json
  7. 85 0
      apps/backend-mock/api/system/user/list.ts
  8. 5 3
      apps/web-antd/src/adapter/component/index.ts
  9. 5 3
      apps/web-antdv-next/src/adapter/component/index.ts
  10. 5 3
      apps/web-ele/src/adapter/component/index.ts
  11. 5 3
      apps/web-naive/src/adapter/component/index.ts
  12. 5 3
      apps/web-tdesign/src/adapter/component/index.ts
  13. 2 0
      docs/.vitepress/build/dayjs-loader.mjs
  14. 10 0
      docs/.vitepress/build/dayjs-resolve-hook.mjs
  15. 2 2
      docs/.vitepress/config/index.mts
  16. 20 3
      docs/.vitepress/config/shared.mts
  17. 5 5
      docs/.vitepress/config/zh.mts
  18. 1 1
      docs/.vitepress/theme/components/site-layout.vue
  19. 3 2
      docs/package.json
  20. 5 6
      docs/src/_env/adapter/component.ts
  21. 1 1
      docs/src/_env/adapter/vxe-table.ts
  22. 1 1
      docs/src/components/common-ui/vben-api-component.md
  23. 1 1
      docs/src/components/common-ui/vben-form.md
  24. 1 1
      docs/src/components/common-ui/vben-vxe-table.md
  25. 1 1
      docs/src/demos/vben-alert/alert/index.vue
  26. 1 1
      docs/src/demos/vben-alert/confirm/index.vue
  27. 1 1
      docs/src/demos/vben-alert/prompt/index.vue
  28. 1 1
      docs/src/demos/vben-api-component/cascader/index.vue
  29. 1 1
      docs/src/demos/vben-form/api/index.vue
  30. 1 1
      docs/src/demos/vben-form/basic/index.vue
  31. 1 1
      docs/src/demos/vben-form/custom/index.vue
  32. 1 1
      docs/src/demos/vben-form/dynamic/index.vue
  33. 1 1
      docs/src/demos/vben-form/query/index.vue
  34. 1 1
      docs/src/demos/vben-form/rules/index.vue
  35. 1 1
      docs/src/demos/vben-form/value-format/index.vue
  36. 1 1
      docs/src/demos/vben-vxe-table/basic/index.vue
  37. 1 1
      docs/src/demos/vben-vxe-table/custom-cell/index.vue
  38. 1 1
      docs/src/demos/vben-vxe-table/edit-row/index.vue
  39. 1 1
      docs/src/demos/vben-vxe-table/fixed/index.vue
  40. 1 1
      docs/src/demos/vben-vxe-table/form/index.vue
  41. 1 1
      docs/src/demos/vben-vxe-table/remote/index.vue
  42. 1 1
      docs/src/demos/vben-vxe-table/tree/index.vue
  43. 1 1
      docs/src/en/components/common-ui/vben-api-component.md
  44. 1 1
      docs/src/en/components/common-ui/vben-form.md
  45. 5 5
      docs/src/en/guide/essentials/external-module.md
  46. 1 1
      docs/src/en/guide/essentials/server.md
  47. 1 1
      docs/src/en/guide/other/faq.md
  48. 5 5
      docs/src/guide/essentials/external-module.md
  49. 1 1
      docs/src/guide/essentials/server.md
  50. 1 1
      docs/src/guide/in-depth/check-updates.md
  51. 1 1
      docs/src/guide/other/faq.md
  52. 1 0
      internal/lint-configs/oxlint-config/src/configs/comments.ts
  53. 70 0
      internal/vite-config/src/plugins/dayjs.ts
  54. 7 0
      internal/vite-config/src/plugins/index.ts
  55. 5 0
      internal/vite-config/src/typing.ts
  56. 2 2
      package.json
  57. 1 1
      packages/@core/base/shared/src/cache/indexeddb-driver.ts
  58. 1 1
      packages/@core/base/shared/src/cache/local-storage-driver.ts
  59. 1 1
      packages/@core/base/shared/src/cache/memory-storage-driver.ts
  60. 2 2
      packages/@core/base/shared/src/cache/storage-manager.ts
  61. 1 1
      packages/@core/base/shared/src/cache/types.ts
  62. 3 1
      packages/@core/base/shared/src/utils/__tests__/state-handler.test.ts
  63. 4 2
      packages/@core/base/shared/src/utils/__tests__/util.test.ts
  64. 2 2
      packages/@core/base/shared/src/utils/state-handler.ts
  65. 1 5
      packages/@core/preferences/src/preferences.ts
  66. 1 0
      packages/effects/plugins/src/tiptap/extensions.ts
  67. 12 13
      packages/effects/plugins/src/vxe-table/use-viewed-row.ts
  68. 9 15
      packages/effects/request/src/request-client/request-client.test.ts
  69. 1 1
      playground/package.json
  70. 70 54
      playground/src/adapter/component/index.ts
  71. 1 1
      playground/src/adapter/vxe-table.ts
  72. 1 1
      playground/src/api/request.ts
  73. 1 0
      playground/src/api/system/index.ts
  74. 55 0
      playground/src/api/system/user.ts
  75. 10 2
      playground/src/app.vue
  76. 1 1
      playground/src/bootstrap.ts
  77. 3 3
      playground/src/locales/index.ts
  78. 13 0
      playground/src/locales/langs/en-US/system.json
  79. 13 0
      playground/src/locales/langs/zh-CN/system.json
  80. 1 1
      playground/src/main.ts
  81. 1 1
      playground/src/router/access.ts
  82. 9 0
      playground/src/router/routes/modules/system.ts
  83. 2 2
      playground/src/store/auth.ts
  84. 1 1
      playground/src/views/_core/authentication/code-login.vue
  85. 1 1
      playground/src/views/_core/profile/password-setting.vue
  86. 1 1
      playground/src/views/demos/access/button-control.vue
  87. 1 1
      playground/src/views/demos/access/index.vue
  88. 1 1
      playground/src/views/demos/badge/index.vue
  89. 1 1
      playground/src/views/demos/breadcrumb/lateral-detail.vue
  90. 1 1
      playground/src/views/demos/breadcrumb/lateral.vue
  91. 1 1
      playground/src/views/demos/features/clipboard/index.vue
  92. 1 1
      playground/src/views/demos/features/file-download/index.vue
  93. 1 1
      playground/src/views/demos/features/full-screen/index.vue
  94. 1 1
      playground/src/views/demos/features/icons/index.vue
  95. 2 2
      playground/src/views/demos/features/json-bigint/index.vue
  96. 1 1
      playground/src/views/demos/features/login-expired/index.vue
  97. 3 3
      playground/src/views/demos/features/preferences-extension/index.vue
  98. 1 1
      playground/src/views/demos/features/request-params-serializer/index.vue
  99. 1 1
      playground/src/views/demos/features/tabs/index.vue
  100. 2 2
      playground/src/views/demos/features/vue-query/index.vue

+ 0 - 5
.changeset/element-plus-theme-switch.md

@@ -1,5 +0,0 @@
----
-'@vben/layouts': patch
----
-
-fix: update primary color when toggling dark/light mode with custom theme

+ 0 - 5
.changeset/page-auto-content-height.md

@@ -1,5 +0,0 @@
----
-'@vben/common-ui': patch
----
-
-fix: skip fixed footer height in auto-content-height calculation

+ 0 - 5
.changeset/small-moons-hunt.md

@@ -1,5 +0,0 @@
----
-'@vben/icons': patch
----
-
-fix: guard svg icon loading during docs SSR

+ 0 - 5
.changeset/tree-default-value.md

@@ -1,5 +0,0 @@
----
-'@vben-core/shadcn-ui': patch
----
-
-fix: preserve tree default value when treeData starts empty

+ 0 - 12
.npmrc

@@ -1,13 +1 @@
 registry=https://registry.npmmirror.com
-public-hoist-pattern[]=lefthook
-public-hoist-pattern[]=eslint
-public-hoist-pattern[]=oxfmt
-public-hoist-pattern[]=oxlint
-public-hoist-pattern[]=stylelint
-public-hoist-pattern[]=*postcss*
-public-hoist-pattern[]=@commitlint/*
-public-hoist-pattern[]=czg
-
-strict-peer-dependencies=false
-auto-install-peers=true
-dedupe-peer-dependents=true

+ 1 - 1
.vscode/settings.json

@@ -38,7 +38,7 @@
 
   // lint && format
   "oxc.enable": true,
-  "oxc.typeAware": true,
+  "oxc.typeAware": false,
   "oxc.configPath": "oxlint.config.ts",
   "oxc.fmt.configPath": "oxfmt.config.ts",
   "eslint.useFlatConfig": true,

+ 85 - 0
apps/backend-mock/api/system/user/list.ts

@@ -0,0 +1,85 @@
+import { faker } from '@faker-js/faker';
+import { eventHandler, getQuery } from 'h3';
+import { verifyAccessToken } from '~/utils/jwt-utils';
+import { unAuthorizedResponse, usePageResponseSuccess } from '~/utils/response';
+
+const formatterCN = new Intl.DateTimeFormat('zh-CN', {
+  timeZone: 'Asia/Shanghai',
+  year: 'numeric',
+  month: '2-digit',
+  day: '2-digit',
+  hour: '2-digit',
+  minute: '2-digit',
+  second: '2-digit',
+});
+
+function generateMockDataList(count: number) {
+  const dataList = [];
+
+  for (let i = 0; i < count; i++) {
+    const dataItem: Record<string, any> = {
+      id: faker.string.uuid(),
+      name: faker.commerce.product(),
+      status: faker.helpers.arrayElement([0, 1]),
+      createTime: formatterCN.format(
+        faker.date.between({ from: '2022-01-01', to: '2025-01-01' }),
+      ),
+      deptId: faker.string.uuid(),
+      remark: faker.lorem.sentence(),
+    };
+
+    dataList.push(dataItem);
+  }
+
+  return dataList;
+}
+
+const mockData = generateMockDataList(100);
+
+export default eventHandler(async (event) => {
+  const userinfo = verifyAccessToken(event);
+  if (!userinfo) {
+    return unAuthorizedResponse(event);
+  }
+
+  const {
+    page = 1,
+    pageSize = 20,
+    name,
+    id,
+    remark,
+    startTime,
+    endTime,
+    deptId,
+    status,
+  } = getQuery(event);
+  let listData = structuredClone(mockData);
+  if (name) {
+    listData = listData.filter((item) =>
+      item.name.toLowerCase().includes(String(name).toLowerCase()),
+    );
+  }
+  if (id) {
+    listData = listData.filter((item) =>
+      item.id.toLowerCase().includes(String(id).toLowerCase()),
+    );
+  }
+  if (remark) {
+    listData = listData.filter((item) =>
+      item.remark?.toLowerCase()?.includes(String(remark).toLowerCase()),
+    );
+  }
+  if (startTime) {
+    listData = listData.filter((item) => item.createTime >= startTime);
+  }
+  if (endTime) {
+    listData = listData.filter((item) => item.createTime <= endTime);
+  }
+  if (['0', '1'].includes(status as string)) {
+    listData = listData.filter((item) => item.status === Number(status));
+  }
+  if (deptId) {
+    listData = listData.filter((item) => item.deptId === deptId);
+  }
+  return usePageResponseSuccess(page as string, pageSize as string, listData);
+});

+ 5 - 3
apps/web-antd/src/adapter/component/index.ts

@@ -131,8 +131,8 @@ const PreviewGroup = defineAsyncComponent(() =>
   import('ant-design-vue/es/image').then((res) => res.ImagePreviewGroup),
 );
 
-const withDefaultPlaceholder = <T extends Component>(
-  component: T,
+const withDefaultPlaceholder = (
+  component: Component,
   type: 'input' | 'select',
   componentProps: Recordable<any> = {},
 ) => {
@@ -702,7 +702,9 @@ async function initComponentAdapter() {
       modelValueProp: 'value',
     }),
     Input: withDefaultPlaceholder(Input, 'input'),
-    InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
+    InputNumber: withDefaultPlaceholder(InputNumber, 'input', {
+      style: { width: '100%' },
+    }),
     InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
     Mentions: withDefaultPlaceholder(Mentions, 'input'),
     // 自定义主要按钮

+ 5 - 3
apps/web-antdv-next/src/adapter/component/index.ts

@@ -136,8 +136,8 @@ const PreviewGroup = defineAsyncComponent(() =>
   import('antdv-next/dist/image/index').then((res) => res.ImagePreviewGroup),
 );
 
-const withDefaultPlaceholder = <T extends Component>(
-  component: T,
+const withDefaultPlaceholder = (
+  component: Component,
   type: 'input' | 'select',
   componentProps: Recordable<any> = {},
 ) => {
@@ -633,7 +633,9 @@ async function initComponentAdapter() {
       modelValueProp: 'value',
     }),
     Input: withDefaultPlaceholder(Input, 'input'),
-    InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
+    InputNumber: withDefaultPlaceholder(InputNumber, 'input', {
+      style: { width: '100%' },
+    }),
     InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
     Mentions: withDefaultPlaceholder(Mentions, 'input'),
     // 自定义主要按钮

+ 5 - 3
apps/web-ele/src/adapter/component/index.ts

@@ -141,8 +141,8 @@ const ElUpload = defineAsyncComponent(() =>
   ]).then(([res]) => res.ElUpload),
 );
 
-const withDefaultPlaceholder = <T extends Component>(
-  component: T,
+const withDefaultPlaceholder = (
+  component: Component,
   type: 'input' | 'select',
   componentProps: Recordable<any> = {},
 ) => {
@@ -284,7 +284,9 @@ async function initComponentAdapter() {
       inputComponent: ElInput,
     }),
     Input: withDefaultPlaceholder(ElInput, 'input'),
-    InputNumber: withDefaultPlaceholder(ElInputNumber, 'input'),
+    InputNumber: withDefaultPlaceholder(ElInputNumber, 'input', {
+      style: { width: '100%' },
+    }),
     RadioGroup: (props, { attrs, slots }) => {
       let defaultSlot;
       if (Reflect.has(slots, 'default')) {

+ 5 - 3
apps/web-naive/src/adapter/component/index.ts

@@ -84,8 +84,8 @@ const NUpload = defineAsyncComponent(() =>
   import('naive-ui/es/upload').then((res) => res.NUpload),
 );
 
-const withDefaultPlaceholder = <T extends Component>(
-  component: T,
+const withDefaultPlaceholder = (
+  component: Component,
   type: 'input' | 'select',
   componentProps: Recordable<any> = {},
 ) => {
@@ -225,7 +225,9 @@ async function initComponentAdapter() {
       inputComponent: NInput,
     }),
     Input: withDefaultPlaceholder(NInput, 'input'),
-    InputNumber: withDefaultPlaceholder(NInputNumber, 'input'),
+    InputNumber: withDefaultPlaceholder(NInputNumber, 'input', {
+      style: { width: '100%' },
+    }),
     RadioGroup: (props, { attrs, slots }) => {
       let defaultSlot;
       if (Reflect.has(slots, 'default')) {

+ 5 - 3
apps/web-tdesign/src/adapter/component/index.ts

@@ -89,8 +89,8 @@ const TreeSelect = defineAsyncComponent(
 );
 const Upload = defineAsyncComponent(() => import('tdesign-vue-next/es/upload'));
 
-const withDefaultPlaceholder = <T extends Component>(
-  component: T,
+const withDefaultPlaceholder = (
+  component: Component,
   type: 'input' | 'select',
   componentProps: Recordable<any> = {},
 ) => {
@@ -239,7 +239,9 @@ async function initComponentAdapter() {
       modelValueProp: 'value',
     }),
     Input: withDefaultPlaceholder(Input, 'input'),
-    InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
+    InputNumber: withDefaultPlaceholder(InputNumber, 'input', {
+      style: { width: '100%' },
+    }),
     // InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
     // Mentions: withDefaultPlaceholder(Mentions, 'input'),
     // 自定义主要按钮

+ 2 - 0
docs/.vitepress/build/dayjs-loader.mjs

@@ -0,0 +1,2 @@
+import { register } from 'node:module';
+register('./dayjs-resolve-hook.mjs', import.meta.url);

+ 10 - 0
docs/.vitepress/build/dayjs-resolve-hook.mjs

@@ -0,0 +1,10 @@
+const DAYJS_SUBPATH_RE = /^dayjs\/(plugin|locale)\/([^./]+)$/;
+
+/** @type {import('node:module').ResolveHook} */
+export async function resolve(specifier, context, nextResolve) {
+  const match = specifier.match(DAYJS_SUBPATH_RE);
+  if (match) {
+    return nextResolve(`${specifier}.js`, context);
+  }
+  return nextResolve(specifier, context);
+}

+ 2 - 2
docs/.vitepress/config/index.mts

@@ -1,12 +1,12 @@
 import { withPwa } from '@vite-pwa/vitepress';
-import { defineConfigWithTheme } from 'vitepress';
+import { defineConfig } from 'vitepress';
 
 import { en } from './en.mts';
 import { shared } from './shared.mts';
 import { zh } from './zh.mts';
 
 export default withPwa(
-  defineConfigWithTheme({
+  defineConfig({
     ...shared,
     locales: {
       en: {

+ 20 - 3
docs/.vitepress/config/shared.mts

@@ -5,6 +5,7 @@ import { resolve } from 'node:path';
 
 import {
   viteArchiverPlugin,
+  viteDayjsPlugin,
   viteVxeTableImportsPlugin,
 } from '@vben/vite-config';
 
@@ -61,7 +62,7 @@ export const shared = defineConfig({
       },
       preprocessorOptions: {
         scss: {
-          api: 'modern',
+          // api: 'modern',
         },
       },
     },
@@ -69,6 +70,7 @@ export const shared = defineConfig({
       stringify: true,
     },
     plugins: [
+      viteDayjsPlugin(),
       tailwindcss(),
       GitChangelog({
         mapAuthors: [
@@ -85,9 +87,23 @@ export const shared = defineConfig({
             name: 'Li Kui',
             username: 'likui628',
           },
+          {
+            mapByNameAliases: ['Jin Mao', 'jinmao'],
+            name: 'Jin Mao',
+            username: 'jinmao88',
+          },
+          {
+            name: 'Netfan',
+            username: 'mynetfan',
+          },
+          {
+            mapByNameAliases: ['xingyu4j', 'xingyu'],
+            name: 'xingyu4j',
+            username: 'xingyu4j',
+          },
         ],
         repoURL: () => 'https://github.com/vbenjs/vue-vben-admin',
-      }),
+      }) as any,
       GitChangelogMarkdownSection(),
       viteArchiverPlugin({ outputDir: '.vitepress' }),
       groupIconVitePlugin(),
@@ -103,6 +119,7 @@ export const shared = defineConfig({
 
     ssr: {
       external: ['@vue/repl'],
+      noExternal: ['@v-c/picker'],
     },
   },
 });
@@ -113,7 +130,7 @@ function head(): HeadConfig[] {
     [
       'meta',
       {
-        content: 'vben, vitejs, vite, shacdn-ui, vue',
+        content: 'vben, vitejs, vite, shadcn-ui, vue',
         name: 'keywords',
       },
     ],

+ 5 - 5
docs/.vitepress/config/zh.mts

@@ -337,8 +337,8 @@ export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
         footer: {
           closeText: '关闭',
           navigateText: '切换',
-          searchByText: '搜索提供者',
           selectText: '选择',
+          poweredByText: '搜索提供者',
         },
         noResultsScreen: {
           noResultsText: '无法找到相关结果',
@@ -347,10 +347,10 @@ export const search: DefaultTheme.AlgoliaSearchOptions['locales'] = {
           suggestedQueryText: '你可以尝试查询',
         },
         searchBox: {
-          cancelButtonAriaLabel: '取消',
-          cancelButtonText: '取消',
-          resetButtonAriaLabel: '清除查询条件',
-          resetButtonTitle: '清除查询条件',
+          closeButtonAriaLabel: '取消',
+          closeButtonText: '取消',
+          clearButtonAriaLabel: '清除查询条件',
+          clearButtonTitle: '清除查询条件',
         },
         startScreen: {
           favoriteSearchesTitle: '收藏',

+ 1 - 1
docs/.vitepress/theme/components/site-layout.vue

@@ -10,7 +10,7 @@ import {
 
 // import { useAntdDesignTokens } from '@vben/hooks';
 // import { initPreferences } from '@vben/preferences';
-import { ConfigProvider, theme } from 'ant-design-vue';
+import { ConfigProvider, theme } from 'antdv-next';
 import mediumZoom from 'medium-zoom';
 import { useRoute } from 'vitepress';
 import DefaultTheme from 'vitepress/theme';

+ 3 - 2
docs/package.json

@@ -2,8 +2,9 @@
   "name": "@vben/docs",
   "version": "5.7.0",
   "private": true,
+  "type": "module",
   "scripts": {
-    "build": "vitepress build",
+    "build": "cross-env NODE_OPTIONS=\"--import ./.vitepress/build/dayjs-loader.mjs\" vitepress build",
     "dev": "vitepress dev",
     "docs:preview": "vitepress preview"
   },
@@ -19,7 +20,7 @@
     "@vben/locales": "workspace:*",
     "@vben/plugins": "workspace:*",
     "@vben/styles": "workspace:*",
-    "ant-design-vue": "catalog:",
+    "antdv-next": "catalog:",
     "lucide-vue-next": "catalog:",
     "medium-zoom": "catalog:",
     "reka-ui": "catalog:",

+ 5 - 6
docs/src/_env/adapter/component.ts

@@ -26,16 +26,15 @@ import {
   notification,
   Radio,
   RadioGroup,
-  RangePicker,
   Rate,
   Select,
   Space,
   Switch,
-  Textarea,
+  TextArea,
   TimePicker,
   TreeSelect,
   Upload,
-} from 'ant-design-vue';
+} from 'antdv-next';
 
 const withDefaultPlaceholder = <T extends Component>(
   component: T,
@@ -98,12 +97,12 @@ async function initComponentAdapter() {
     },
     Radio,
     RadioGroup,
-    RangePicker,
+    RangePicker: withDefaultPlaceholder(DatePicker.RangePicker, 'select'),
     Rate,
     Select: withDefaultPlaceholder(Select, 'select'),
     Space,
     Switch,
-    Textarea: withDefaultPlaceholder(Textarea, 'input'),
+    Textarea: withDefaultPlaceholder(TextArea, 'input'),
     TimePicker,
     TreeSelect: withDefaultPlaceholder(TreeSelect, 'select'),
     Upload,
@@ -118,7 +117,7 @@ async function initComponentAdapter() {
     copyPreferencesSuccess: (title, content) => {
       notification.success({
         description: content,
-        message: title,
+        title,
         placement: 'bottomRight',
       });
     },

+ 1 - 1
docs/src/_env/adapter/vxe-table.ts

@@ -2,7 +2,7 @@ import { h } from 'vue';
 
 import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
 
-import { Button, Image } from 'ant-design-vue';
+import { Button, Image } from 'antdv-next';
 
 import { useVbenForm } from './form';
 

+ 1 - 1
docs/src/components/common-ui/vben-api-component.md

@@ -22,7 +22,7 @@ outline: deep
 <script lang="ts" setup>
 import { ApiComponent } from '@vben/common-ui';
 
-import { Cascader } from 'ant-design-vue';
+import { Cascader } from 'antdv-next';
 
 const treeData: Record<string, any> = [
   {

+ 1 - 1
docs/src/components/common-ui/vben-form.md

@@ -117,7 +117,7 @@ import {
   TimePicker,
   TreeSelect,
   Upload,
-} from 'ant-design-vue';
+} from 'antdv-next';
 
 const withDefaultPlaceholder = <T extends Component>(
   component: T,

+ 1 - 1
docs/src/components/common-ui/vben-vxe-table.md

@@ -25,7 +25,7 @@ import { h } from 'vue';
 
 import { setupVbenVxeTable, useVbenVxeGrid } from '@vben/plugins/vxe-table';
 
-import { Button, Image } from 'ant-design-vue';
+import { Button, Image } from 'antdv-next';
 
 import { useVbenForm } from './form';
 

+ 1 - 1
docs/src/demos/vben-alert/alert/index.vue

@@ -3,7 +3,7 @@ import { h } from 'vue';
 
 import { alert, VbenButton } from '@vben/common-ui';
 
-import { Result } from 'ant-design-vue';
+import { Result } from 'antdv-next';
 
 function showAlert() {
   alert('This is an alert message');

+ 1 - 1
docs/src/demos/vben-alert/confirm/index.vue

@@ -3,7 +3,7 @@ import { h, ref } from 'vue';
 
 import { alert, confirm, VbenButton } from '@vben/common-ui';
 
-import { Checkbox, message } from 'ant-design-vue';
+import { Checkbox, message } from 'antdv-next';
 
 function showConfirm() {
   confirm('This is an alert message')

+ 1 - 1
docs/src/demos/vben-alert/prompt/index.vue

@@ -3,7 +3,7 @@ import { h } from 'vue';
 
 import { alert, prompt, useAlertContext, VbenButton } from '@vben/common-ui';
 
-import { Input, RadioGroup, Select } from 'ant-design-vue';
+import { Input, RadioGroup, Select } from 'antdv-next';
 import { BadgeJapaneseYen } from 'lucide-vue-next';
 
 function showPrompt() {

+ 1 - 1
docs/src/demos/vben-api-component/cascader/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import { ApiComponent } from '@vben/common-ui';
 
-import { Cascader } from 'ant-design-vue';
+import { Cascader } from 'antdv-next';
 
 const treeData: Record<string, any> = [
   {

+ 1 - 1
docs/src/demos/vben-form/api/index.vue

@@ -1,5 +1,5 @@
 <script lang="ts" setup>
-import { Button, message, Space } from 'ant-design-vue';
+import { Button, message, Space } from 'antdv-next';
 
 import { useVbenForm } from '#/adapter/form';
 

+ 1 - 1
docs/src/demos/vben-form/basic/index.vue

@@ -1,5 +1,5 @@
 <script lang="ts" setup>
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { useVbenForm } from '#/adapter/form';
 

+ 1 - 1
docs/src/demos/vben-form/custom/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import { h } from 'vue';
 
-import { Input, message } from 'ant-design-vue';
+import { Input, message } from 'antdv-next';
 
 import { useVbenForm } from '#/adapter/form';
 

+ 1 - 1
docs/src/demos/vben-form/dynamic/index.vue

@@ -1,5 +1,5 @@
 <script lang="ts" setup>
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { useVbenForm } from '#/adapter/form';
 

+ 1 - 1
docs/src/demos/vben-form/query/index.vue

@@ -1,5 +1,5 @@
 <script lang="ts" setup>
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { useVbenForm } from '#/adapter/form';
 

+ 1 - 1
docs/src/demos/vben-form/rules/index.vue

@@ -1,5 +1,5 @@
 <script lang="ts" setup>
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { useVbenForm, z } from '#/adapter/form';
 

+ 1 - 1
docs/src/demos/vben-form/value-format/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import { computed, nextTick, onMounted, ref, watch } from 'vue';
 
-import { Button, Card, message, Space, Tag } from 'ant-design-vue';
+import { Button, Card, message, Space, Tag } from 'antdv-next';
 
 import { useVbenForm } from '#/adapter/form';
 

+ 1 - 1
docs/src/demos/vben-vxe-table/basic/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import type { VxeGridListeners, VxeGridProps } from '#/adapter/vxe-table';
 
-import { Button, message } from 'ant-design-vue';
+import { Button, message } from 'antdv-next';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 

+ 1 - 1
docs/src/demos/vben-vxe-table/custom-cell/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
-import { Button, Image, Switch, Tag } from 'ant-design-vue';
+import { Button, Image, Switch, Tag } from 'antdv-next';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 

+ 1 - 1
docs/src/demos/vben-vxe-table/edit-row/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
-import { Button, message } from 'ant-design-vue';
+import { Button, message } from 'antdv-next';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 

+ 1 - 1
docs/src/demos/vben-vxe-table/fixed/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
-import { Button } from 'ant-design-vue';
+import { Button } from 'antdv-next';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 

+ 1 - 1
docs/src/demos/vben-vxe-table/form/index.vue

@@ -2,7 +2,7 @@
 import type { VbenFormProps } from '#/adapter/form';
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 

+ 1 - 1
docs/src/demos/vben-vxe-table/remote/index.vue

@@ -3,7 +3,7 @@ import type { DemoTableApi } from '../mock-api';
 
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
-import { Button } from 'ant-design-vue';
+import { Button } from 'antdv-next';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 

+ 1 - 1
docs/src/demos/vben-vxe-table/tree/index.vue

@@ -1,7 +1,7 @@
 <script lang="ts" setup>
 import type { VxeGridProps } from '#/adapter/vxe-table';
 
-import { Button } from 'ant-design-vue';
+import { Button } from 'antdv-next';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
 

+ 1 - 1
docs/src/en/components/common-ui/vben-api-component.md

@@ -20,7 +20,7 @@ The current wrapper flow is:
 <script lang="ts" setup>
 import { ApiComponent } from '@vben/common-ui';
 
-import { Cascader } from 'ant-design-vue';
+import { Cascader } from 'antdv-next';
 
 function fetchApi() {
   return Promise.resolve([

+ 1 - 1
docs/src/en/components/common-ui/vben-form.md

@@ -103,7 +103,7 @@ import {
   TimePicker,
   TreeSelect,
   Upload,
-} from 'ant-design-vue';
+} from 'antdv-next';
 
 const withDefaultPlaceholder = <T extends Component>(
   component: T,

+ 5 - 5
docs/src/en/guide/essentials/external-module.md

@@ -1,6 +1,6 @@
 # External Modules
 
-In addition to the external modules that are included by default in the project, sometimes we need to import other external modules. Let's take [ant-design-vue](https://antdv.com/components/overview) as an example:
+In addition to the external modules that are included by default in the project, sometimes we need to import other external modules. Let's take [antdv-next](https://antdv.com/components/overview) as an example:
 
 ## Installing Dependencies
 
@@ -13,7 +13,7 @@ In addition to the external modules that are included by default in the project,
 
 ```bash
 # cd /path/to/your/package
-pnpm add ant-design-vue
+pnpm add antdv-next
 ```
 
 ## Usage
@@ -22,9 +22,9 @@ pnpm add ant-design-vue
 
 ```ts
 import { createApp } from 'vue';
-import Antd from 'ant-design-vue';
+import Antd from 'antdv-next';
 import App from './App';
-import 'ant-design-vue/dist/reset.css';
+import 'antdv-next/dist/reset.css';
 
 const app = createApp(App);
 
@@ -43,7 +43,7 @@ app.use(Antd).mount('#app');
 
 ```vue
 <script setup lang="ts">
-import { Button } from 'ant-design-vue';
+import { Button } from 'antdv-next';
 </script>
 
 <template>

+ 1 - 1
docs/src/en/guide/essentials/server.md

@@ -174,7 +174,7 @@ import {
 } from '@vben/request';
 import { useAccessStore } from '@vben/stores';
 
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { useAuthStore } from '#/store';
 

+ 1 - 1
docs/src/en/guide/other/faq.md

@@ -110,7 +110,7 @@ registry = https://registry.npmmirror.com/
 If you encounter errors similar to the following, please check that the full project path (including all parent paths) does not contain Chinese, Japanese, or Korean characters. Otherwise, you will encounter a 404 error for the path, leading to the following issue:
 
 ```ts
-[vite] Failed to resolve module import "ant-design-vue/dist/antd.css-vben-adminode_modulesant-design-vuedistantd.css". (imported by /@/setup/ant-design-vue/index.ts)
+[vite] Failed to resolve module import "antdv-next/dist/antd.css-vben-adminode_modulesantdv-nextdistantd.css". (imported by /@/setup/antdv-next/index.ts)
 ```
 
 ## Console Route Warning Issue

+ 5 - 5
docs/src/guide/essentials/external-module.md

@@ -1,6 +1,6 @@
 # 外部模块
 
-除了项目默认引入的外部模块,有时我们还需要引入其他外部模块。我们以 [ant-design-vue](https://antdv.com/components/overview) 为例:
+除了项目默认引入的外部模块,有时我们还需要引入其他外部模块。我们以 [antdv-next](https://antdv.com/components/overview) 为例:
 
 ## 安装依赖
 
@@ -13,7 +13,7 @@
 
 ```bash
 # cd /path/to/your/package
-pnpm add ant-design-vue
+pnpm add antdv-next
 ```
 
 ## 使用
@@ -22,9 +22,9 @@ pnpm add ant-design-vue
 
 ```ts
 import { createApp } from 'vue';
-import Antd from 'ant-design-vue';
+import Antd from 'antdv-next';
 import App from './App';
-import 'ant-design-vue/dist/reset.css';
+import 'antdv-next/dist/reset.css';
 
 const app = createApp(App);
 
@@ -43,7 +43,7 @@ app.use(Antd).mount('#app');
 
 ```vue
 <script setup lang="ts">
-import { Button } from 'ant-design-vue';
+import { Button } from 'antdv-next';
 </script>
 
 <template>

+ 1 - 1
docs/src/guide/essentials/server.md

@@ -204,7 +204,7 @@ import {
 } from '@vben/request';
 import { useAccessStore } from '@vben/stores';
 
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { useAuthStore } from '#/store';
 

+ 1 - 1
docs/src/guide/in-depth/check-updates.md

@@ -60,7 +60,7 @@ pnpm add version-polling
 ```ts
 import { h } from 'vue';
 
-import { Button, notification } from 'ant-design-vue';
+import { Button, notification } from 'antdv-next';
 import { createVersionPolling } from 'version-polling';
 
 createVersionPolling({

+ 1 - 1
docs/src/guide/other/faq.md

@@ -110,7 +110,7 @@ registry = https://registry.npmmirror.com/
 如果出现类似以下错误,请检查项目全路径(包含所有父级路径)不能出现中文、日文、韩文。否则将会出现路径访问 404 导致以下问题
 
 ```ts
-[vite] Failed to resolve module import "ant-design-vue/dist/antd.css-vben-adminode_modulesant-design-vuedistantd.css". (imported by /@/setup/ant-design-vue/index.ts)
+[vite] Failed to resolve module import "antdv-next/dist/antd.css-vben-adminode_modulesantdv-nextdistantd.css". (imported by /@/setup/antdv-next/index.ts)
 ```
 
 ## 控制台路由警告问题

+ 1 - 0
internal/lint-configs/oxlint-config/src/configs/comments.ts

@@ -8,6 +8,7 @@ const comments: OxlintConfig = {
     },
   ],
   rules: {
+    'eslint/no-underscore-dangle': 'off',
     'eslint-comments/no-aggregating-enable': 'error',
     'eslint-comments/no-duplicate-disable': 'error',
     'eslint-comments/no-unlimited-disable': 'error',

+ 70 - 0
internal/vite-config/src/plugins/dayjs.ts

@@ -0,0 +1,70 @@
+import type { Plugin } from 'vite';
+
+function viteDayjsPlugin(): Plugin {
+  return {
+    name: 'vite-dayjs-plugin',
+    enforce: 'pre',
+    async resolveId(source, importer, options) {
+      // 1) 已经使用了 dayjs/esm 的不处理
+      if (source.startsWith('dayjs/esm')) return null;
+
+      // 2) 根入口:dayjs -> dayjs/esm
+      if (source === 'dayjs') {
+        return await this.resolve('dayjs/esm', importer, {
+          skipSelf: true,
+          ...options,
+        });
+      }
+
+      // 3) 插件入口的多种写法
+      //    - dayjs/plugin/xxx.js           -> dayjs/esm/plugin/xxx/index.js
+      //    - dayjs/plugin/xxx              -> dayjs/esm/plugin/xxx
+      const pluginWithJs = source.match(/^dayjs\/plugin\/([^/]+)\.js$/);
+      if (pluginWithJs) {
+        const target = `dayjs/esm/plugin/${pluginWithJs[1]}/index.js`;
+        return await this.resolve(target, importer, {
+          skipSelf: true,
+          ...options,
+        });
+      }
+
+      const pluginBare = source.match(/^dayjs\/plugin\/([^/]+)$/);
+      if (pluginBare) {
+        const target = `dayjs/esm/plugin/${pluginBare[1]}`;
+        return await this.resolve(target, importer, {
+          skipSelf: true,
+          ...options,
+        });
+      }
+
+      // 4) 处理多语言包
+      //    - dayjs/locale/xxx.js          -> dayjs/esm/locale/xxx.js
+      const localeWithJs = source.match(/^dayjs\/locale\/([^/]+)\.js$/);
+      if (localeWithJs) {
+        const target = `dayjs/esm/locale/${localeWithJs[1]}.js`;
+        return await this.resolve(target, importer, {
+          skipSelf: true,
+          ...options,
+        });
+      }
+      const localeBare = source.match(/^dayjs\/locale\/([^/]+)$/);
+      if (localeBare) {
+        const target = `dayjs/esm/locale/${localeBare[1]}`;
+        return await this.resolve(target, importer, {
+          skipSelf: true,
+          ...options,
+        });
+      }
+
+      return null;
+    },
+    config() {
+      return {
+        optimizeDeps: {
+          exclude: ['dayjs'],
+        },
+      };
+    },
+  };
+}
+export { viteDayjsPlugin };

+ 7 - 0
internal/vite-config/src/plugins/index.ts

@@ -18,6 +18,7 @@ import { VitePWA } from 'vite-plugin-pwa';
 import viteVueDevTools from 'vite-plugin-vue-devtools';
 
 import { viteArchiverPlugin } from './archiver';
+import { viteDayjsPlugin } from './dayjs';
 import { viteExtraAppConfigPlugin } from './extra-app-config';
 import { viteHtmlPlugin } from './html';
 import { viteImportMapPlugin } from './importmap';
@@ -105,6 +106,7 @@ async function loadApplicationPlugins(
     compressTypes,
     extraAppConfig,
     html,
+    dayjs,
     i18n,
     importmap,
     importmapOptions,
@@ -219,6 +221,10 @@ async function loadApplicationPlugins(
         return [await viteArchiverPlugin(archiverPluginOptions)];
       },
     },
+    {
+      condition: dayjs,
+      plugins: () => [viteDayjsPlugin()],
+    },
   ]);
 }
 
@@ -247,6 +253,7 @@ export {
   loadLibraryPlugins,
   viteArchiverPlugin,
   viteCompressPlugin,
+  viteDayjsPlugin,
   viteDtsPlugin,
   viteHtmlPlugin,
   viteVisualizerPlugin,

+ 5 - 0
internal/vite-config/src/typing.ts

@@ -214,6 +214,11 @@ interface ApplicationPluginOptions extends CommonPluginOptions {
    * @description 可选的压缩类型
    */
   compressTypes?: ('brotli' | 'gzip')[];
+  /**
+   * 是否开启 dayjs 插件
+   * @default true
+   */
+  dayjs?: boolean;
   /**
    * 是否抽离配置文件
    * @default false

+ 2 - 2
package.json

@@ -102,8 +102,8 @@
     "vue-tsc": "catalog:"
   },
   "engines": {
-    "node": "^20.19.0 || ^22.18.0 || ^24.0.0",
+    "node": "^22.18.0 || ^24.0.0",
     "pnpm": ">=10.0.0"
   },
-  "packageManager": "pnpm@10.33.0"
+  "packageManager": "pnpm@10.33.4"
 }

+ 1 - 1
packages/@core/base/shared/src/cache/indexeddb-driver.ts

@@ -87,7 +87,7 @@ class IndexedDBDriver implements IStorageDriver {
     });
   }
 
-  async setItem<T>(key: string, value: T): Promise<void> {
+  async setItem(key: string, value: unknown): Promise<void> {
     const db = await this.getDB();
     return new Promise((resolve, reject) => {
       const tx = db.transaction(this.storeName, 'readwrite');

+ 1 - 1
packages/@core/base/shared/src/cache/local-storage-driver.ts

@@ -62,7 +62,7 @@ class LocalStorageDriver implements IStorageDriver {
     this.storage.removeItem(key);
   }
 
-  async setItem<T>(key: string, value: T): Promise<void> {
+  async setItem(key: string, value: unknown): Promise<void> {
     this.storage.setItem(key, JSON.stringify(value));
   }
 }

+ 1 - 1
packages/@core/base/shared/src/cache/memory-storage-driver.ts

@@ -24,7 +24,7 @@ class MemoryStorageDriver implements IStorageDriver {
     this.store.delete(key);
   }
 
-  async setItem<T>(key: string, value: T): Promise<void> {
+  async setItem(key: string, value: unknown): Promise<void> {
     this.store.set(key, value);
   }
 }

+ 2 - 2
packages/@core/base/shared/src/cache/storage-manager.ts

@@ -106,10 +106,10 @@ class StorageManager {
    * @param value 值
    * @param ttl 存活时间(毫秒)
    */
-  async setItem<T>(key: string, value: T, ttl?: number): Promise<void> {
+  async setItem(key: string, value: unknown, ttl?: number): Promise<void> {
     const fullKey = this.getFullKey(key);
     const expiry = ttl ? Date.now() + ttl : undefined;
-    const item: StorageItem<T> = { expiry, value };
+    const item: StorageItem<unknown> = { expiry, value };
     await this.driver.setItem(fullKey, item);
   }
 

+ 1 - 1
packages/@core/base/shared/src/cache/types.ts

@@ -17,7 +17,7 @@ interface IStorageDriver {
   removeItem(key: string): Promise<void>;
 
   /** 设置存储项 */
-  setItem<T>(key: string, value: T): Promise<void>;
+  setItem(key: string, value: unknown): Promise<void>;
 }
 
 /**

+ 3 - 1
packages/@core/base/shared/src/utils/__tests__/state-handler.test.ts

@@ -34,7 +34,9 @@ describe('stateHandler', () => {
     }, 10);
 
     // 等待过程中,期望 Promise 被 reject
-    await expect(handler.waitForCondition()).rejects.toThrow();
+    await expect(handler.waitForCondition()).rejects.toThrow(
+      'Condition was set to false',
+    );
     expect(handler.isConditionTrue()).toBe(false);
   });
 

+ 4 - 2
packages/@core/base/shared/src/utils/__tests__/util.test.ts

@@ -138,8 +138,10 @@ describe('getNestedValue', () => {
     expect(result).toBe(2);
   });
 
-  it('should return the entire object if path is empty', () => {
-    expect(() => getNestedValue(data, '')()).toThrow();
+  it('should throw if path is empty', () => {
+    expect(() => getNestedValue(data, '')).toThrow(
+      'Path must be a non-empty string',
+    );
   });
 
   it('should handle paths with array indexes', () => {

+ 2 - 2
packages/@core/base/shared/src/utils/state-handler.ts

@@ -1,6 +1,6 @@
 export class StateHandler {
   private condition: boolean = false;
-  private rejectCondition: (() => void) | null = null;
+  private rejectCondition: ((reason?: Error) => void) | null = null;
   private resolveCondition: (() => void) | null = null;
 
   isConditionTrue(): boolean {
@@ -16,7 +16,7 @@ export class StateHandler {
   setConditionFalse() {
     this.condition = false;
     if (this.rejectCondition) {
-      this.rejectCondition();
+      this.rejectCondition(new Error('Condition was set to false'));
       this.clearPromises();
     }
   }

+ 1 - 5
packages/@core/preferences/src/preferences.ts

@@ -180,11 +180,7 @@ class PreferenceManager {
    * 更新扩展偏好设置
    * @param updates - 要更新的扩展偏好设置
    */
-  updateCustomPreferences = <
-    TCustomPreferences extends object = CustomPreferencesRecord,
-  >(
-    updates: DeepPartial<TCustomPreferences>,
-  ) => {
+  updateCustomPreferences = (updates: DeepPartial<object>) => {
     if (!this.customPreferencesExtension) {
       return;
     }

+ 1 - 0
packages/effects/plugins/src/tiptap/extensions.ts

@@ -66,6 +66,7 @@ function findPlaceholderPos(doc: ProseMirrorNode, blobUrl: string): number {
       found = offset;
       return false;
     }
+    return true;
   });
   return found;
 }

+ 12 - 13
packages/effects/plugins/src/vxe-table/use-viewed-row.ts

@@ -1,3 +1,4 @@
+/* eslint-disable unicorn/no-nested-ternary */
 import type { VxeGridProps as VxeTableGridProps } from 'vxe-table';
 
 import type {
@@ -182,13 +183,11 @@ export function useViewedRow<T = any>(
   options: ViewedRowOptions<T> & { keyField: string },
 ) {
   // ========== 解析持久化配置 ==========
-  let persistOpts: null | ViewedRowPersistOptions = null;
-  if (options.persist) {
-    persistOpts =
-      typeof options.persist === 'string'
-        ? { key: options.persist, type: 'localStorage' }
-        : options.persist;
-  }
+  const persistOpts: null | ViewedRowPersistOptions = options.persist
+    ? typeof options.persist === 'string'
+      ? { key: options.persist, type: 'localStorage' }
+      : options.persist
+    : null;
 
   const adapter = createStorageAdapter(options.persist);
   const maxSize = persistOpts?.maxSize ?? 100;
@@ -521,12 +520,12 @@ export function applyViewedRowOptions(
   };
 
   // 拦截 CellOperation columns
-  let actionCodes: string[] = [];
-  if (!isBoolean(viewedRowConfig) && viewedRowConfig.actionCodes) {
-    actionCodes = Array.isArray(viewedRowConfig.actionCodes)
-      ? viewedRowConfig.actionCodes
-      : [viewedRowConfig.actionCodes];
-  }
+  const actionCodes =
+    !isBoolean(viewedRowConfig) && viewedRowConfig.actionCodes
+      ? Array.isArray(viewedRowConfig.actionCodes)
+        ? viewedRowConfig.actionCodes
+        : [viewedRowConfig.actionCodes]
+      : [];
 
   if (actionCodes.length > 0 && Array.isArray(mergedOptions.columns)) {
     mergedOptions.columns = wrapColumnsForViewedRow(

+ 9 - 15
packages/effects/request/src/request-client/request-client.test.ts

@@ -50,24 +50,18 @@ describe('requestClient', () => {
 
   it('should handle network errors', async () => {
     mock.onGet('/test/error').networkError();
-    try {
-      await requestClient.get('/test/error');
-      expect(true).toBe(false);
-    } catch (error: any) {
-      expect(error.isAxiosError).toBe(true);
-      expect(error.message).toBe('Network Error');
-    }
+    await expect(requestClient.get('/test/error')).rejects.toMatchObject({
+      isAxiosError: true,
+      message: 'Network Error',
+    });
   });
 
   it('should handle timeout', async () => {
     mock.onGet('/test/timeout').timeout();
-    try {
-      await requestClient.get('/test/timeout');
-      expect(true).toBe(false);
-    } catch (error: any) {
-      expect(error.isAxiosError).toBe(true);
-      expect(error.code).toBe('ECONNABORTED');
-    }
+    await expect(requestClient.get('/test/timeout')).rejects.toMatchObject({
+      isAxiosError: true,
+      code: 'ECONNABORTED',
+    });
   });
 
   it('should successfully upload a file', async () => {
@@ -92,7 +86,7 @@ describe('requestClient', () => {
 
     mock.onGet('/test/download').reply(200, mockFileContent);
 
-    const res = await requestClient.download('/test/download');
+    const res = await requestClient.download<any>('/test/download');
 
     expect(res.data).toBeInstanceOf(Blob);
   });

+ 1 - 1
playground/package.json

@@ -48,7 +48,7 @@
     "@vben/types": "workspace:*",
     "@vben/utils": "workspace:*",
     "@vueuse/core": "catalog:",
-    "ant-design-vue": "catalog:",
+    "antdv-next": "catalog:",
     "dayjs": "catalog:",
     "json-bigint": "catalog:",
     "pinia": "catalog:",

+ 70 - 54
playground/src/adapter/component/index.ts

@@ -18,6 +18,7 @@ import type {
   MentionsProps,
   RadioGroupProps,
   RadioProps,
+  RangePickerProps,
   RateProps,
   SelectProps,
   SpaceProps,
@@ -28,8 +29,7 @@ import type {
   UploadChangeParam,
   UploadFile,
   UploadProps,
-} from 'ant-design-vue';
-import type { RangePickerProps } from 'ant-design-vue/es/date-picker';
+} from 'antdv-next';
 
 import type { Component, Ref } from 'vue';
 
@@ -72,7 +72,7 @@ import { isEmpty } from '@vben/utils';
 
 import { VbenCollapsibleParams } from '@vben-core/shadcn-ui';
 
-import { message, Modal, notification } from 'ant-design-vue';
+import { message, Modal, notification } from 'antdv-next';
 
 import { upload_file } from '#/api/examples/upload';
 type AdapterUploadProps = UploadProps & {
@@ -86,60 +86,72 @@ type AdapterUploadProps = UploadProps & {
 };
 
 const AutoComplete = defineAsyncComponent(
-  () => import('ant-design-vue/es/auto-complete'),
+  () => import('antdv-next/dist/auto-complete/index'),
+);
+const Button = defineAsyncComponent(
+  () => import('antdv-next/dist/button/index'),
 );
-const Button = defineAsyncComponent(() => import('ant-design-vue/es/button'));
 const Checkbox = defineAsyncComponent(
-  () => import('ant-design-vue/es/checkbox'),
+  () => import('antdv-next/dist/checkbox/index'),
 );
 const CheckboxGroup = defineAsyncComponent(() =>
-  import('ant-design-vue/es/checkbox').then((res) => res.CheckboxGroup),
+  import('antdv-next/dist/checkbox/index').then((res) => res.CheckboxGroup),
 );
 const DatePicker = defineAsyncComponent(
-  () => import('ant-design-vue/es/date-picker'),
+  () => import('antdv-next/dist/date-picker/index'),
+);
+const Divider = defineAsyncComponent(
+  () => import('antdv-next/dist/divider/index'),
 );
-const Divider = defineAsyncComponent(() => import('ant-design-vue/es/divider'));
-const Input = defineAsyncComponent(() => import('ant-design-vue/es/input'));
+const Input = defineAsyncComponent(() => import('antdv-next/dist/input/index'));
 const InputNumber = defineAsyncComponent(
-  () => import('ant-design-vue/es/input-number'),
+  () => import('antdv-next/dist/input-number/index'),
 );
 const InputPassword = defineAsyncComponent(() =>
-  import('ant-design-vue/es/input').then((res) => res.InputPassword),
+  import('antdv-next/dist/input/index').then((res) => res.InputPassword),
 );
 const Mentions = defineAsyncComponent(
-  () => import('ant-design-vue/es/mentions'),
+  () => import('antdv-next/dist/mentions/index'),
 );
-const Radio = defineAsyncComponent(() => import('ant-design-vue/es/radio'));
+const Radio = defineAsyncComponent(() => import('antdv-next/dist/radio/index'));
 const RadioGroup = defineAsyncComponent(() =>
-  import('ant-design-vue/es/radio').then((res) => res.RadioGroup),
+  import('antdv-next/dist/radio/index').then((res) => res.RadioGroup),
 );
 const RangePicker = defineAsyncComponent(() =>
-  import('ant-design-vue/es/date-picker').then((res) => res.RangePicker),
+  import('antdv-next/dist/date-picker/index').then(
+    (res) => res.DateRangePicker,
+  ),
+);
+const Rate = defineAsyncComponent(() => import('antdv-next/dist/rate/index'));
+const Select = defineAsyncComponent(
+  () => import('antdv-next/dist/select/index'),
 );
-const Rate = defineAsyncComponent(() => import('ant-design-vue/es/rate'));
-const Select = defineAsyncComponent(() => import('ant-design-vue/es/select'));
-const Space = defineAsyncComponent(() => import('ant-design-vue/es/space'));
-const Switch = defineAsyncComponent(() => import('ant-design-vue/es/switch'));
-const Textarea = defineAsyncComponent(() =>
-  import('ant-design-vue/es/input').then((res) => res.Textarea),
+const Space = defineAsyncComponent(() => import('antdv-next/dist/space/index'));
+const Switch = defineAsyncComponent(
+  () => import('antdv-next/dist/switch/index'),
+);
+const Textarea = defineAsyncComponent(
+  () => import('antdv-next/dist/input/TextArea'),
 );
 const TimePicker = defineAsyncComponent(
-  () => import('ant-design-vue/es/time-picker'),
+  () => import('antdv-next/dist/time-picker/index'),
 );
 const TreeSelect = defineAsyncComponent(
-  () => import('ant-design-vue/es/tree-select'),
+  () => import('antdv-next/dist/tree-select/index'),
 );
 const Cascader = defineAsyncComponent(
-  () => import('ant-design-vue/es/cascader'),
+  () => import('antdv-next/dist/cascader/index'),
+);
+const Upload = defineAsyncComponent(
+  () => import('antdv-next/dist/upload/index'),
 );
-const Upload = defineAsyncComponent(() => import('ant-design-vue/es/upload'));
-const Image = defineAsyncComponent(() => import('ant-design-vue/es/image'));
+const Image = defineAsyncComponent(() => import('antdv-next/dist/image/index'));
 const PreviewGroup = defineAsyncComponent(() =>
-  import('ant-design-vue/es/image').then((res) => res.ImagePreviewGroup),
+  import('antdv-next/dist/image/index').then((res) => res.ImagePreviewGroup),
 );
 
-const withDefaultPlaceholder = <T extends Component>(
-  component: T,
+const withDefaultPlaceholder = (
+  component: Component,
   type: 'input' | 'select',
   componentProps: Recordable<any> = {},
 ) => {
@@ -242,7 +254,7 @@ function getBase64(file: File): Promise<string> {
  */
 async function previewImage(
   file: UploadFile,
-  visible: Ref<boolean>,
+  open: Ref<boolean>,
   fileList: Ref<UploadProps['fileList']>,
 ) {
   // 非图片文件直接打开链接
@@ -250,6 +262,8 @@ async function previewImage(
     const url = file.url || file.preview;
     if (url) {
       window.open(url, '_blank');
+    } else if (file.preview) {
+      window.open(file.preview, '_blank');
     } else {
       message.error($t('ui.formRules.previewWarning'));
     }
@@ -285,10 +299,10 @@ async function previewImage(
           {
             class: 'hidden',
             preview: {
-              visible: visible.value,
+              open: open.value,
               current: currentIndex,
-              onVisibleChange: (value: boolean) => {
-                visible.value = value;
+              onOpenChange: (value: boolean) => {
+                open.value = value;
                 if (!value) {
                   setTimeout(() => {
                     if (!isUnmounted && container) {
@@ -330,7 +344,7 @@ function cropImage(file: File, aspectRatio: string | undefined) {
     const open = ref<boolean>(true);
     const cropperRef = ref<InstanceType<typeof VCropper> | null>(null);
 
-    const closeModal = () => {
+    function closeModal() {
       open.value = false;
       setTimeout(() => {
         if (!isUnmounted && container) {
@@ -342,7 +356,7 @@ function cropImage(file: File, aspectRatio: string | undefined) {
           container.remove();
         }
       }, 300);
-    };
+    }
 
     const CropperWrapper = {
       setup() {
@@ -372,7 +386,7 @@ function cropImage(file: File, aspectRatio: string | undefined) {
               closable: false,
               cancelText: $t('common.cancel'),
               okText: $t('ui.crop.confirm'),
-              destroyOnClose: true,
+              destroyOnHidden: true,
               onOk: async () => {
                 const cropper = cropperRef.value;
                 if (!cropper) {
@@ -416,7 +430,7 @@ function cropImage(file: File, aspectRatio: string | undefined) {
 /**
  * 带预览功能的上传组件
  */
-const withPreviewUpload = () => {
+function withPreviewUpload() {
   return defineComponent({
     name: Upload.name,
     emits: ['update:modelValue'],
@@ -436,10 +450,10 @@ const withPreviewUpload = () => {
         () => attrs?.aspectRatio ?? attrs?.['aspect-ratio'],
       );
 
-      const handleBeforeUpload = async (
+      async function handleBeforeUpload(
         file: UploadFile,
         originFileList: Array<File>,
-      ) => {
+      ) {
         // 文件大小限制
         if (maxSize.value && (file.size || 0) / 1024 / 1024 > maxSize.value) {
           message.error($t('ui.formRules.sizeLimit', [maxSize.value]));
@@ -463,9 +477,9 @@ const withPreviewUpload = () => {
         }
 
         return attrs.beforeUpload?.(file) ?? true;
-      };
+      }
 
-      const handleChange = (event: UploadChangeParam) => {
+      function handleChange(event: UploadChangeParam) {
         try {
           attrs.handleChange?.(event);
           attrs.onHandleChange?.(event);
@@ -479,19 +493,19 @@ const withPreviewUpload = () => {
           'update:modelValue',
           event.fileList?.length ? fileList.value : undefined,
         );
-      };
+      }
 
-      const handlePreview = async (file: UploadFile) => {
+      function handlePreview(file: UploadFile) {
         previewVisible.value = true;
-        await previewImage(file, previewVisible, fileList);
-      };
+        return previewImage(file, previewVisible, fileList);
+      }
 
-      const renderUploadButton = () => {
+      function renderUploadButton() {
         if (attrs.disabled) return null;
         return isEmpty(slots)
           ? createDefaultUploadSlots(listType, placeholder)
           : slots;
-      };
+      }
 
       // 拖拽排序
       const draggable = computed(
@@ -600,7 +614,7 @@ const withPreviewUpload = () => {
         );
     },
   });
-};
+}
 
 // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明
 export type ComponentType =
@@ -681,13 +695,13 @@ async function initComponentAdapter() {
       fieldNames: { label: 'label', value: 'value', children: 'children' },
       loadingSlot: 'suffixIcon',
       modelPropName: 'value',
-      visibleEvent: 'onVisibleChange',
+      visibleEvent: 'onOpenChange',
     }),
     ApiSelect: withDefaultPlaceholder(ApiComponent, 'select', {
       component: Select,
       loadingSlot: 'suffixIcon',
       modelPropName: 'value',
-      visibleEvent: 'onVisibleChange',
+      visibleEvent: 'onOpenChange',
     }),
     ApiTreeSelect: withDefaultPlaceholder(ApiComponent, 'select', {
       component: TreeSelect,
@@ -695,7 +709,7 @@ async function initComponentAdapter() {
       loadingSlot: 'suffixIcon',
       modelPropName: 'value',
       optionsPropName: 'treeData',
-      visibleEvent: 'onVisibleChange',
+      visibleEvent: 'onOpenChange',
     }),
     AutoComplete,
     Cascader,
@@ -713,7 +727,9 @@ async function initComponentAdapter() {
       modelValueProp: 'value',
     }),
     Input: withDefaultPlaceholder(Input, 'input'),
-    InputNumber: withDefaultPlaceholder(InputNumber, 'input'),
+    InputNumber: withDefaultPlaceholder(InputNumber, 'input', {
+      style: { width: '100%' },
+    }),
     InputPassword: withDefaultPlaceholder(InputPassword, 'input'),
     Mentions: withDefaultPlaceholder(Mentions, 'input'),
     // 自定义主要按钮
@@ -764,7 +780,7 @@ async function initComponentAdapter() {
     copyPreferencesSuccess: (title, content) => {
       notification.success({
         description: content,
-        message: title,
+        title,
         placement: 'bottomRight',
       });
     },

+ 1 - 1
playground/src/adapter/vxe-table.ts

@@ -14,7 +14,7 @@ import {
 import { get, isFunction, isString } from '@vben/utils';
 
 import { objectOmit } from '@vueuse/core';
-import { Button, Image, Popconfirm, Switch, Tag } from 'ant-design-vue';
+import { Button, Image, Popconfirm, Switch, Tag } from 'antdv-next';
 
 import { $t } from '#/locales';
 

+ 1 - 1
playground/src/api/request.ts

@@ -14,7 +14,7 @@ import {
 import { useAccessStore } from '@vben/stores';
 import { cloneDeep } from '@vben/utils';
 
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 import JSONBigInt from 'json-bigint';
 
 import { useAuthStore } from '#/store';

+ 1 - 0
playground/src/api/system/index.ts

@@ -1,3 +1,4 @@
 export * from './dept';
 export * from './menu';
 export * from './role';
+export * from './user';

+ 55 - 0
playground/src/api/system/user.ts

@@ -0,0 +1,55 @@
+import type { Recordable } from '@vben/types';
+
+import { requestClient } from '#/api/request';
+
+export namespace SystemUserApi {
+  export interface SystemUser {
+    [key: string]: any;
+    id: string;
+    name: string;
+    permissions: string[];
+    remark?: string;
+    status: 0 | 1;
+  }
+}
+
+/**
+ * 获取用户列表数据
+ */
+async function getUserList(params: Recordable<any>) {
+  return requestClient.get<Array<SystemUserApi.SystemUser>>(
+    '/system/user/list',
+    { params },
+  );
+}
+
+/**
+ * 创建用户
+ * @param data 用户数据
+ */
+async function createUser(data: Omit<SystemUserApi.SystemUser, 'id'>) {
+  return requestClient.post('/system/user', data);
+}
+
+/**
+ * 更新用户
+ *
+ * @param id 用户 ID
+ * @param data 用户数据
+ */
+async function updateUser(
+  id: string,
+  data: Omit<SystemUserApi.SystemUser, 'id'>,
+) {
+  return requestClient.put(`/system/user/${id}`, data);
+}
+
+/**
+ * 删除用户
+ * @param id 用户 ID
+ */
+async function deleteUser(id: string) {
+  return requestClient.delete(`/system/user/${id}`);
+}
+
+export { createUser, deleteUser, getUserList, updateUser };

+ 10 - 2
playground/src/app.vue

@@ -1,10 +1,10 @@
 <script lang="ts" setup>
-import { computed } from 'vue';
+import { computed, watch } from 'vue';
 
 import { useAntdDesignTokens } from '@vben/hooks';
 import { preferences, usePreferences } from '@vben/preferences';
 
-import { App, ConfigProvider, theme } from 'ant-design-vue';
+import { App, ConfigProvider, theme } from 'antdv-next';
 
 import { antdLocale } from '#/locales';
 
@@ -28,6 +28,14 @@ const tokenTheme = computed(() => {
     token: tokens,
   };
 });
+
+watch(
+  tokenTheme,
+  (themeConfig) => {
+    ConfigProvider.config({ theme: themeConfig });
+  },
+  { immediate: true },
+);
 </script>
 
 <template>

+ 1 - 1
playground/src/bootstrap.ts

@@ -6,7 +6,7 @@ import { providePluginsOptions } from '@vben/plugins';
 import { preferences } from '@vben/preferences';
 import { initStores } from '@vben/stores';
 import '@vben/styles';
-import '@vben/styles/antd';
+import '@vben/styles/antdv-next';
 
 import { useTitle } from '@vueuse/core';
 

+ 3 - 3
playground/src/locales/index.ts

@@ -1,4 +1,4 @@
-import type { Locale } from 'ant-design-vue/es/locale';
+import type { Locale } from 'antdv-next/dist/locale/index';
 
 import type { App } from 'vue';
 
@@ -13,8 +13,8 @@ import {
 } from '@vben/locales';
 import { preferences } from '@vben/preferences';
 
-import antdEnLocale from 'ant-design-vue/es/locale/en_US';
-import antdDefaultLocale from 'ant-design-vue/es/locale/zh_CN';
+import antdEnLocale from 'antdv-next/dist/locale/en_US';
+import antdDefaultLocale from 'antdv-next/dist/locale/zh_CN';
 import dayjs from 'dayjs';
 
 const antdLocale = ref<Locale>(antdDefaultLocale);

+ 13 - 0
playground/src/locales/langs/en-US/system.json

@@ -1,5 +1,18 @@
 {
   "title": "System Management",
+  "user": {
+    "title": "User Management",
+    "list": "User List",
+    "name": "User",
+    "userName": "User Name",
+    "id": "User ID",
+    "dept": "Department",
+    "status": "Status",
+    "remark": "Remark",
+    "createTime": "Creation Time",
+    "operation": "Operation",
+    "placeholder": "Search Department..."
+  },
   "dept": {
     "name": "Department",
     "title": "Department Management",

+ 13 - 0
playground/src/locales/langs/zh-CN/system.json

@@ -1,5 +1,18 @@
 {
   "title": "系统管理",
+  "user": {
+    "title": "用户管理",
+    "list": "用户列表",
+    "name": "用户名",
+    "userName": "用户名称",
+    "id": "用户ID",
+    "dept": "部门",
+    "status": "状态",
+    "remark": "备注",
+    "createTime": "创建时间",
+    "operation": "操作",
+    "placeholder": "搜索部门..."
+  },
   "dept": {
     "list": "部门列表",
     "createTime": "创建时间",

+ 1 - 1
playground/src/main.ts

@@ -29,4 +29,4 @@ async function initApplication() {
   unmountGlobalLoading();
 }
 
-initApplication();
+void initApplication();

+ 1 - 1
playground/src/router/access.ts

@@ -6,7 +6,7 @@ import type {
 import { generateAccessible } from '@vben/access';
 import { preferences } from '@vben/preferences';
 
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 import { getAllMenusApi } from '#/api';
 import { BasicLayout, IFrameView } from '#/layouts';

+ 9 - 0
playground/src/router/routes/modules/system.ts

@@ -12,6 +12,15 @@ const routes: RouteRecordRaw[] = [
     name: 'System',
     path: '/system',
     children: [
+      {
+        path: '/system/user',
+        name: 'SystemUser',
+        meta: {
+          icon: 'mdi:user',
+          title: $t('system.user.title'),
+        },
+        component: () => import('#/views/system/user/list.vue'),
+      },
       {
         path: '/system/role',
         name: 'SystemRole',

+ 2 - 2
playground/src/store/auth.ts

@@ -7,7 +7,7 @@ import { LOGIN_PATH } from '@vben/constants';
 import { preferences } from '@vben/preferences';
 import { resetAllStores, useAccessStore, useUserStore } from '@vben/stores';
 
-import { notification } from 'ant-design-vue';
+import { notification } from 'antdv-next';
 import { defineStore } from 'pinia';
 
 import { getAccessCodesApi, getUserInfoApi, loginApi, logoutApi } from '#/api';
@@ -65,7 +65,7 @@ export const useAuthStore = defineStore('auth', () => {
           notification.success({
             description: `${$t('authentication.loginSuccessDesc')}:${userInfo?.realName}`,
             duration: 3,
-            message: $t('authentication.loginSuccess'),
+            title: $t('authentication.loginSuccess'),
           });
         }
       }

+ 1 - 1
playground/src/views/_core/authentication/code-login.vue

@@ -7,7 +7,7 @@ import { computed, ref, useTemplateRef } from 'vue';
 import { AuthenticationCodeLogin, z } from '@vben/common-ui';
 import { $t } from '@vben/locales';
 
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 defineOptions({ name: 'CodeLogin' });
 

+ 1 - 1
playground/src/views/_core/profile/password-setting.vue

@@ -5,7 +5,7 @@ import { computed } from 'vue';
 
 import { ProfilePasswordSetting, z } from '@vben/common-ui';
 
-import { message } from 'ant-design-vue';
+import { message } from 'antdv-next';
 
 const formSchema = computed((): VbenFormSchema[] => {
   return [

+ 1 - 1
playground/src/views/demos/access/button-control.vue

@@ -7,7 +7,7 @@ import { AccessControl, useAccess } from '@vben/access';
 import { Page } from '@vben/common-ui';
 import { resetAllStores, useUserStore } from '@vben/stores';
 
-import { Button, Card } from 'ant-design-vue';
+import { Button, Card } from 'antdv-next';
 
 import { useAuthStore } from '#/store';
 

+ 1 - 1
playground/src/views/demos/access/index.vue

@@ -7,7 +7,7 @@ import { useAccess } from '@vben/access';
 import { Page } from '@vben/common-ui';
 import { resetAllStores, useUserStore } from '@vben/stores';
 
-import { Button, Card } from 'ant-design-vue';
+import { Button, Card } from 'antdv-next';
 
 import { useAuthStore } from '#/store';
 

+ 1 - 1
playground/src/views/demos/badge/index.vue

@@ -7,7 +7,7 @@ import { useAccessStore } from '@vben/stores';
 
 import { MenuBadge } from '@vben-core/menu-ui';
 
-import { Button, Card, Radio, RadioGroup } from 'ant-design-vue';
+import { Button, Card, Radio, RadioGroup } from 'antdv-next';
 
 import { useVbenForm } from '#/adapter/form';
 

+ 1 - 1
playground/src/views/demos/breadcrumb/lateral-detail.vue

@@ -3,7 +3,7 @@ import { useRouter } from 'vue-router';
 
 import { Fallback } from '@vben/common-ui';
 
-import { Button } from 'ant-design-vue';
+import { Button } from 'antdv-next';
 
 const router = useRouter();
 </script>

+ 1 - 1
playground/src/views/demos/breadcrumb/lateral.vue

@@ -3,7 +3,7 @@ import { useRouter } from 'vue-router';
 
 import { Fallback } from '@vben/common-ui';
 
-import { Button } from 'ant-design-vue';
+import { Button } from 'antdv-next';
 
 const router = useRouter();
 

+ 1 - 1
playground/src/views/demos/features/clipboard/index.vue

@@ -4,7 +4,7 @@ import { ref } from 'vue';
 import { Page } from '@vben/common-ui';
 
 import { useClipboard } from '@vueuse/core';
-import { Button, Card, Input } from 'ant-design-vue';
+import { Button, Card, Input } from 'antdv-next';
 
 const source = ref('Hello');
 const { copy, text } = useClipboard({ legacy: true, source });

+ 1 - 1
playground/src/views/demos/features/file-download/index.vue

@@ -9,7 +9,7 @@ import {
   downloadFileFromUrl,
 } from '@vben/utils';
 
-import { Button, Card } from 'ant-design-vue';
+import { Button, Card } from 'antdv-next';
 
 import { downloadFile1, downloadFile2 } from '#/api/examples/download';
 

+ 1 - 1
playground/src/views/demos/features/full-screen/index.vue

@@ -4,7 +4,7 @@ import { ref } from 'vue';
 import { Page } from '@vben/common-ui';
 
 import { useFullscreen } from '@vueuse/core';
-import { Button, Card } from 'ant-design-vue';
+import { Button, Card } from 'antdv-next';
 
 const domRef = ref<HTMLElement>();
 

+ 1 - 1
playground/src/views/demos/features/icons/index.vue

@@ -18,7 +18,7 @@ import {
   SvgWeChatIcon,
 } from '@vben/icons';
 
-import { Card, Input } from 'ant-design-vue';
+import { Card, Input } from 'antdv-next';
 
 const iconValue1 = ref('ant-design:trademark-outlined');
 const iconValue2 = ref('svg:avatar-1');

+ 2 - 2
playground/src/views/demos/features/json-bigint/index.vue

@@ -3,7 +3,7 @@ import { ref } from 'vue';
 
 import { Page } from '@vben/common-ui';
 
-import { Alert, Button, Card } from 'ant-design-vue';
+import { Alert, Button, Card } from 'antdv-next';
 
 import { getBigIntData } from '#/api/examples/json-bigint';
 
@@ -21,7 +21,7 @@ function fetchData() {
   >
     <Card>
       <Alert>
-        <template #message>
+        <template #title>
           有些后端接口返回的ID是长整数,但javascript原生的JSON解析是不支持超过2^53-1的长整数的。
           这种情况可以建议后端返回数据前将长整数转换为字符串类型。如果后端不接受我们的建议😡……
           <br />

+ 1 - 1
playground/src/views/demos/features/login-expired/index.vue

@@ -4,7 +4,7 @@ import type { LoginExpiredModeType } from '@vben/types';
 import { Page } from '@vben/common-ui';
 import { preferences, updatePreferences } from '@vben/preferences';
 
-import { Button, Card } from 'ant-design-vue';
+import { Button, Card } from 'antdv-next';
 
 import { getMockStatusApi } from '#/api';
 

+ 3 - 3
playground/src/views/demos/features/preferences-extension/index.vue

@@ -9,7 +9,7 @@ import {
   updateCustomPreferences,
 } from '@vben/preferences';
 
-import { Alert, Button, Card, Space, Tag } from 'ant-design-vue';
+import { Alert, Button, Card, Space, Tag } from 'antdv-next';
 
 import { $t } from '#/locales';
 
@@ -105,7 +105,7 @@ function applyPreset(type: 'compact' | 'focus' | 'review') {
     },
   };
 
-  updateCustomPreferences<PlaygroundPreferencesExtension>(presetMap[type]);
+  updateCustomPreferences(presetMap[type]);
 }
 
 function getPriorityColor(priority: DemoTaskItem['priority']) {
@@ -136,7 +136,7 @@ function getPriorityColor(priority: DemoTaskItem['priority']) {
       :title="$t('demos.preferencesExtensionDemo.currentConfig')"
     >
       <Alert :type="toneConfig.alertType" show-icon>
-        <template #message>
+        <template #title>
           {{
             $t('demos.preferencesExtensionDemo.currentTitle', {
               title: playgroundPreferences.reportTitle,

+ 1 - 1
playground/src/views/demos/features/request-params-serializer/index.vue

@@ -3,7 +3,7 @@ import { computed, ref, watchEffect } from 'vue';
 
 import { Page } from '@vben/common-ui';
 
-import { Card, Radio, RadioGroup } from 'ant-design-vue';
+import { Card, Radio, RadioGroup } from 'antdv-next';
 
 import { getParamsData } from '#/api/examples/params';
 

+ 1 - 1
playground/src/views/demos/features/tabs/index.vue

@@ -5,7 +5,7 @@ import { useRouter } from 'vue-router';
 import { Page } from '@vben/common-ui';
 import { useTabs } from '@vben/hooks';
 
-import { Button, Card, Input } from 'ant-design-vue';
+import { Button, Card, Input } from 'antdv-next';
 
 const router = useRouter();
 const newTabTitle = ref('');

+ 2 - 2
playground/src/views/demos/features/vue-query/index.vue

@@ -2,7 +2,7 @@
 import { Page } from '@vben/common-ui';
 
 import { refAutoReset } from '@vueuse/core';
-import { Button, Card, Empty } from 'ant-design-vue';
+import { Button, Card, Empty } from 'antdv-next';
 
 import ConcurrencyCaching from './concurrency-caching.vue';
 import InfiniteQueries from './infinite-queries.vue';
@@ -27,7 +27,7 @@ const showCaching = refAutoReset(true, 1000);
       <Card
         title="并发和缓存"
         v-spinning="!showCaching"
-        :body-style="{ minHeight: '330px' }"
+        :styles="{ body: { minHeight: '330px' } }"
       >
         <template #extra>
           <Button @click="showCaching = false">重新加载</Button>

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff