Skip to content

Conversation

@jinmao88
Copy link
Collaborator

@jinmao88 jinmao88 commented Oct 21, 2025

Description

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update
  • Please, don't make changes to pnpm-lock.yaml unless you introduce a new test example.

Checklist

ℹ️ Check all checkboxes - this will indicate that you have done everything in accordance with the rules in CONTRIBUTING.

  • If you introduce new functionality, document it. You can run documentation with pnpm run docs:dev command.
  • Run the tests with pnpm test.
  • Changes in changelog are generated from PR name. Please, make sure that it explains your changes in an understandable manner. Please, prefix changeset messages with feat:, fix:, perf:, docs:, or chore:.
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Summary by CodeRabbit

  • New Features

    • New TDesign-powered web app: bootstrapping, routing, layouts, auth flows, form adapters, table/grid integration, API clients and stores, plus demo pages.
  • UI / UX

    • Complete auth screens (login/code/QR/register/forgot), workspace and analytics dashboards with interactive charts, notifications, validated forms, fallback pages, and en/zh localization.
  • Chores

    • Added environment configs, build/dev scripts, workspace/package setup, conditional analytics injection, and delegated Tailwind/PostCSS config.
  • Content

    • New icon and external TDesign preview route.

@jinmao88 jinmao88 requested review from a team, anncwb, mynetfan and vince292007 as code owners October 21, 2025 04:13
@changeset-bot
Copy link

changeset-bot bot commented Oct 21, 2025

⚠️ No Changeset found

Latest commit: 83ea27a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 21, 2025

Walkthrough

Adds a new TDesign-based Vue 3 app at apps/web-tdesign: project config, env files, Vite/TS configs, package manifest, app entry/bootstrap, adapters (components/form/vxe/tdesign), request/auth clients, API wrappers, router + guards + routes, Pinia auth store, i18n loader and locale files, layouts, many views, icons/constants, and docs/workspace updates.

Changes

Cohort / File(s) Summary
Env & TS / Vite
apps/web-tdesign/.env, apps/web-tdesign/.env.analyze, apps/web-tdesign/.env.development, apps/web-tdesign/.env.production, apps/web-tdesign/vite.config.mts, apps/web-tdesign/tsconfig.json, apps/web-tdesign/tsconfig.node.json
Add app-specific envs (dev/analyze/prod), Vite proxy, and project TypeScript configs.
Package & Tooling
apps/web-tdesign/package.json, apps/web-tdesign/postcss.config.mjs, apps/web-tdesign/tailwind.config.mjs, root package.json, vben-admin.code-workspace
New package manifest, re-export PostCSS/Tailwind configs, add top-level scripts (build:tdesign, dev:tdesign), and workspace folder.
HTML & App Init
apps/web-tdesign/index.html, apps/web-tdesign/src/main.ts, apps/web-tdesign/src/bootstrap.ts, apps/web-tdesign/src/app.vue, apps/web-tdesign/src/preferences.ts
New HTML entry, app bootstrap flow, app component, and preferences overrides.
Adapters
apps/web-tdesign/src/adapter/component/index.ts, apps/web-tdesign/src/adapter/form.ts, apps/web-tdesign/src/adapter/vxe-table.ts, apps/web-tdesign/src/adapter/tdesign.ts
Component async wrappers and withDefaultPlaceholder HOF, typed form initializer, VXE-Table integration with custom renderers, and tdesign plugin re-exports.
API & Request
apps/web-tdesign/src/api/request.ts, apps/web-tdesign/src/api/core/*.ts, apps/web-tdesign/src/api/index.ts
Request client factory with auth/refresh/error interceptors and core API wrappers (auth, user, menu) plus barrel export.
Router & Routes
apps/web-tdesign/src/router/index.ts, apps/web-tdesign/src/router/guard.ts, apps/web-tdesign/src/router/access.ts, apps/web-tdesign/src/router/routes/**
Router creation, scroll behavior, common + access guards, dynamic menu/route generation, core and module routes (dashboard, demos, vben entries).
State / Store
apps/web-tdesign/src/store/auth.ts, apps/web-tdesign/src/store/index.ts
Pinia auth store (authLogin/logout/fetchUserInfo) and store index re-export.
i18n / Locales
apps/web-tdesign/src/locales/index.ts, apps/web-tdesign/src/locales/README.md, apps/web-tdesign/src/locales/langs/*/*.json
Dynamic locale loader, Day.js locale syncing, setupI18n and EN/CN locale JSONs.
Layouts
apps/web-tdesign/src/layouts/index.ts, apps/web-tdesign/src/layouts/basic.vue, apps/web-tdesign/src/layouts/auth.vue
Lazy-loaded layouts, watermark handling, user menu, notifications, and auth modal wiring.
Views — Core, Auth, Fallbacks
apps/web-tdesign/src/views/_core/**
Many core views: about, auth pages (login/register/code/qr/forget), fallback pages (404/403/500/offline/coming-soon).
Views — Dashboard & Demos
apps/web-tdesign/src/views/dashboard/**, apps/web-tdesign/src/views/demos/tdesign/index.vue
Analytics components (ECharts), workspace UI, and TDesign demo page (messages/notifications).
Cross-app locale & routes updates
apps/web-*/src/locales/**, apps/web-*/src/router/routes/modules/vben.ts, packages/@core/base/shared/src/constants/vben.ts, packages/icons/src/svg/index.ts
Add "tdesign" locale keys across apps, new VBEN_TD_PREVIEW_URL constant, SvgTDesignIcon export, and IFrame route entries linking to TDesign preview.
Docs / README
apps/web-tdesign/src/views/_core/README.md, docs/**
Add core views README and update docs examples to include web-tdesign build scripts.

Sequence Diagram(s)

%% App bootstrap high-level flow
sequenceDiagram
    participant main as main.ts
    participant prefs as initPreferences
    participant bootstrap as bootstrap(namespace)
    participant App as Vue App
    participant Router as Router

    main->>prefs: initPreferences(namespace)
    main->>bootstrap: import & await bootstrap(namespace)
    bootstrap->>bootstrap: initComponentAdapter(), initSetupVbenForm()
    bootstrap->>App: createApp(App) + use(Pinia, i18n, router)
    bootstrap->>Router: createRouterGuard(router)
    bootstrap->>App: mount('#app')
    Note right of bootstrap: dynamic imports (tippy, Motion) and directives
Loading
%% Login flow
sequenceDiagram
    participant User
    participant LoginComp as Login Component
    participant AuthStore
    participant API
    participant Router

    User->>LoginComp: submit credentials
    LoginComp->>AuthStore: authLogin(params)
    AuthStore->>API: loginApi(params)
    API-->>AuthStore: accessToken
    AuthStore->>API: getUserInfoApi()
    API-->>AuthStore: userInfo
    AuthStore->>AuthStore: store token & userInfo, fetch access codes
    AuthStore->>Router: navigate to home (or redirect)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas to inspect closely:

  • Router guards and dynamic route/menu generation (src/router/guard.ts, src/router/access.ts, src/router/index.ts)
  • Request client interceptors, token refresh and re-authentication (src/api/request.ts, src/api/core/auth.ts)
  • Component adapter HOF behavior, async wrappers and exported ComponentType (src/adapter/component/index.ts)
  • VXE-Table adapter configuration and cell renderers (src/adapter/vxe-table.ts)
  • Bootstrap initialization ordering and awaited setup functions (src/bootstrap.ts, src/main.ts)

Possibly related PRs

Suggested labels

feature

Suggested reviewers

  • mynetfan
  • anncwb
  • vince292007
  • jinmao88

Poem

🐰 I hopped through code with tiny paws,
I stitched new routes and user laws,
Charts and locales, icons in tow,
A TDesign meadow helps apps grow,
Rabbity cheers — the build says "go!"

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is empty except for the template structure. No actual description, rationale, or implementation details are provided. Provide a comprehensive description of the changes, including what was added, why it was added, and any relevant implementation details or migration notes.
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: adding a new TDesign-based app to the project.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch tdesign

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7bfd69 and 83ea27a.

📒 Files selected for processing (2)
  • apps/web-tdesign/src/api/request.ts (1 hunks)
  • apps/web-tdesign/src/router/access.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web-tdesign/src/router/access.ts
  • apps/web-tdesign/src/api/request.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: post-update (windows-latest)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: Lint (ubuntu-latest)
  • GitHub Check: Check (windows-latest)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: Lint (windows-latest)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 23

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/@core/ui-kit/layout-ui/src/vben-layout.vue (1)

557-564: Add accessibility label to the toggle button.

The toggle button lacks an aria-label attribute, making it inaccessible to screen reader users who won't know the button's purpose.

Apply this diff to improve accessibility:

 <VbenIconButton
   v-if="showHeaderToggleButton"
+  :aria-label="showSidebar ? 'Collapse sidebar' : 'Expand sidebar'"
   class="my-0 mr-1 rounded-md"
   @click="handleHeaderToggle"
 >
   <IconifyIcon v-if="showSidebar" icon="ep:fold" />
   <IconifyIcon v-else icon="ep:expand" />
 </VbenIconButton>
🧹 Nitpick comments (27)
packages/@core/base/design/src/css/ui.css (1)

1-84: Consider documenting animation constants and accessibility implications.

Animations with larger distances and longer durations can impact users with motion sensitivities. If not already handled elsewhere in the codebase, consider ensuring prefers-reduced-motion media queries are in place to respect user preferences.

If animation parameters are used frequently across the design system, consider extracting magic numbers (0.3s, 50px) into CSS custom properties for maintainability:

+:root {
+  --animation-duration-medium: 0.3s;
+  --animation-distance-medium: 50px;
+}
+
 .side-content {
-  animation-duration: 0.3s;
+  animation-duration: var(--animation-duration-medium);
packages/effects/layouts/src/widgets/lock-screen/lock-screen.vue (1)

78-84: Consider extracting the auto-focus logic to a shared utility.

This auto-focus pattern is duplicated in lock-screen-modal.vue (lines 64-70). Extracting it to a shared helper would improve maintainability.

Additionally, the querySelector('[name="password"]') approach relies on internal component DOM structure. If the underlying form component changes its implementation, this could break silently. Consider whether the form library provides a more direct API for focusing fields.

Example shared utility:

// shared/utils/form-focus.ts
export function focusFormField(
  getFieldComponentRef: (name: string) => any,
  fieldName: string
) {
  requestAnimationFrame(() => {
    getFieldComponentRef(fieldName)
      ?.$el?.querySelector(`[name="${fieldName}"]`)
      ?.focus();
  });
}

Then use it as:

  if (showUnlockForm.value) {
-   requestAnimationFrame(() => {
-     getFieldComponentRef('password')
-       ?.$el?.querySelector('[name="password"]')
-       ?.focus();
-   });
+   focusFormField(getFieldComponentRef, 'password');
  }
packages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vue (1)

64-70: Duplicate auto-focus logic – extract to shared utility.

This auto-focus implementation duplicates the same pattern from lock-screen.vue (lines 78-84). Both files use identical logic with requestAnimationFrame and querySelector, which should be extracted to a shared utility function for better maintainability.

See the comment on lock-screen.vue lines 78-84 for a suggested refactoring approach.

apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-source.vue (1)

1-65: LGTM!

The pie chart implementation follows the established Echarts pattern. Hardcoded demo data is appropriate for initial dashboard visualization.

Consider removing the commented-out borderColor at line 40 to keep the code clean:

-        itemStyle: {
-          // borderColor: '#fff',
-          borderRadius: 10,
-          borderWidth: 2,
-        },
+        itemStyle: {
+          borderRadius: 10,
+          borderWidth: 2,
+        },
apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue (1)

22-29: Consider making chart data dynamic.

The chart currently uses hard-coded data values. For production use, consider fetching this data from an API or passing it as props to make the component reusable.

apps/web-tdesign/index.html (1)

17-29: Consider making the analytics tracking ID configurable.

The Baidu analytics tracking ID is hardcoded. For better reusability, consider making it configurable via an environment variable so users can easily use their own tracking ID.

 <script>
   // 生产环境下注入百度统计
   if (window._VBEN_ADMIN_PRO_APP_CONF_) {
+    var trackingId = '<%= VITE_BAIDU_ANALYTICS_ID %>';
+    if (trackingId) {
       var _hmt = _hmt || [];
       (function () {
         var hm = document.createElement('script');
-        hm.src =
-          'https://hm.baidu.com/hm.js?b38e689f40558f20a9a686d7f6f33edf';
+        hm.src = 'https://hm.baidu.com/hm.js?' + trackingId;
         var s = document.getElementsByTagName('script')[0];
         s.parentNode.insertBefore(hm, s);
       })();
+    }
   }
 </script>
apps/web-tdesign/src/locales/langs/zh-CN/page.json (1)

2-13: Namespace mismatch with view usage ("auth" vs "authentication").

The forget-password view uses $t('authentication.') while this file defines "auth.". Ensure consistency or add aliases to prevent missing strings at runtime.

Example addition (if you choose to align on "authentication"):

 {
   "auth": {
     "login": "登录",
     "register": "注册",
     "codeLogin": "验证码登录",
     "qrcodeLogin": "二维码登录",
     "forgetPassword": "忘记密码"
   },
+  "authentication": {
+    "email": "邮箱",
+    "emailTip": "请输入邮箱地址",
+    "emailValidErrorTip": "请输入有效的邮箱地址",
+    "forgetPassword": "忘记密码"
+  },
   "dashboard": {
     "title": "概览",
     "analytics": "分析页",
     "workspace": "工作台"
   }
 }
apps/web-tdesign/src/views/_core/authentication/forget-password.vue (2)

14-29: Localize placeholder; avoid hardcoded English.

Use i18n for the email placeholder to match the rest of the form.

       componentProps: {
-        placeholder: '[email protected]',
+        placeholder: $t('authentication.emailPlaceholder'),
       },

Also add the new key to locale files.


12-12: Wire loading state and replace console.log in submit.

Toggle loading during async submit and surface feedback via UI instead of console.

-const loading = ref(false);
+const loading = ref(false);
+
 async function handleSubmit(value: Recordable<any>) {
-  // eslint-disable-next-line no-console
-  console.log('reset email:', value);
+  try {
+    loading.value = true;
+    // await api.auth.sendResetEmail(value.email);
+    // notify success here
+  } finally {
+    loading.value = false;
+  }
 }

Confirm whether a reset API exists so we can wire it now.

Also applies to: 31-34

apps/web-tdesign/src/locales/index.ts (1)

34-39: Harden i18n fallbacks (messages and antd locale).

Return an empty messages object if none found, and add a default branch for antd locale.

 async function loadMessages(lang: SupportedLanguagesType) {
   const [appLocaleMessages] = await Promise.all([
     localesMap[lang]?.(),
     loadThirdPartyMessage(lang),
   ]);
-  return appLocaleMessages?.default;
+  return appLocaleMessages?.default ?? {};
 }
 async function loadAntdLocale(lang: SupportedLanguagesType) {
   switch (lang) {
     case 'en-US': {
       antdLocale.value = antdEnLocale;
       break;
     }
     case 'zh-CN': {
       antdLocale.value = antdDefaultLocale;
       break;
     }
+    default: {
+      antdLocale.value = antdEnLocale;
+    }
   }
 }

Also applies to: 80-91

apps/web-tdesign/src/router/index.ts (1)

15-30: Optional: enable strict trailing-slash handling and factor history for clarity.

Not required, but improves consistency and readability.

-const router = createRouter({
-  history:
-    import.meta.env.VITE_ROUTER_HISTORY === 'hash'
-      ? createWebHashHistory(import.meta.env.VITE_BASE)
-      : createWebHistory(import.meta.env.VITE_BASE),
+const history =
+  import.meta.env.VITE_ROUTER_HISTORY === 'hash'
+    ? createWebHashHistory(import.meta.env.VITE_BASE)
+    : createWebHistory(import.meta.env.VITE_BASE);
+const router = createRouter({
+  history,
   routes,
   scrollBehavior: (to, _from, savedPosition) => {
     if (savedPosition) {
       return savedPosition;
     }
     return to.hash ? { behavior: 'smooth', el: to.hash } : { left: 0, top: 0 };
   },
-  // strict: true,
+  // strict: true, // consider enabling
 });
apps/web-tdesign/src/views/dashboard/analytics/analytics-visits.vue (1)

6-10: Dispose chart on unmount to avoid leaks.

If useEcharts exposes dispose(), call it on unmount.

-import { onMounted, ref } from 'vue';
+import { onBeforeUnmount, onMounted, ref } from 'vue';
 ...
-const { renderEcharts } = useEcharts(chartRef);
+const { renderEcharts, dispose } = useEcharts(chartRef);
 ...
 onMounted(() => {
   renderEcharts({
     /* ... */
   });
 });
+onBeforeUnmount(() => dispose?.());

Confirm useEcharts exposes dispose; if not, expose it.

apps/web-tdesign/src/bootstrap.ts (1)

28-35: Remove or uncomment modal/drawer configuration.

The commented-out code for setDefaultModalProps and setDefaultDrawerProps should either be removed if not needed or uncommented if these defaults are required. Leaving it commented reduces code clarity.

If not needed, apply this diff:

-  // // 设置弹窗的默认配置
-  // setDefaultModalProps({
-  //   fullscreenButton: false,
-  // });
-  // // 设置抽屉的默认配置
-  // setDefaultDrawerProps({
-  //   zIndex: 1020,
-  // });
-
apps/web-tdesign/src/layouts/basic.vue (2)

79-81: Localize “GitHub” label for consistency.

-    text: 'GitHub',
+    text: $t('ui.widgets.github'),

24-53: Seeded notification copy is hardcoded and not localized.

Consider moving titles/messages/dates to i18n or mock via $t for demo parity.

apps/web-tdesign/src/router/routes/modules/vben.ts (2)

27-27: Use relative child paths to preserve nesting and cleaner route records.

Absolute child paths bypass the parent’s path semantics. Prefer relative paths.

-        path: '/vben-admin/document',
+        path: 'document',
-        path: '/vben-admin/github',
+        path: 'github',
-        path: '/vben-admin/naive',
+        path: 'naive',
-        path: '/vben-admin/ele',
+        path: 'ele',

Also applies to: 37-37, 47-47, 58-58


40-43: Title casing/i18n inconsistency (“Github”).

Use “GitHub” and localize to match others.

-          title: 'Github',
+          title: $t('demos.vben.github'),
apps/web-tdesign/src/views/_core/authentication/register.vue (3)

27-31: Improve UX: add autocomplete hints for password fields.

       componentProps: {
         passwordStrength: true,
-        placeholder: $t('authentication.password'),
+        placeholder: $t('authentication.password'),
+        autocomplete: 'new-password',
       },
...
       componentProps: {
-        placeholder: $t('authentication.confirmPassword'),
+        placeholder: $t('authentication.confirmPassword'),
+        autocomplete: 'new-password',
       },

Also applies to: 42-45


68-74: Avoid empty href which triggers page reload; wire to real URLs safely.

Use actual policy/terms links and open in a new tab with noopener.

-              'a',
-              {
-                class: 'vben-link ml-1 ',
-                href: '',
-              },
+              'a',
+              {
+                class: 'vben-link ml-1',
+                href: '/legal/privacy', // or preferences.app.privacyPolicyUrl
+                target: '_blank',
+                rel: 'noopener noreferrer',
+              },

84-87: Hook submit to backend or store; current handler only logs.

I can wire this to a register API + success flow (toast + redirect). Want a patch?

apps/web-tdesign/src/store/auth.ts (2)

49-51: Redundant setUserInfo call.

fetchUserInfo() already updates userStore; this second set is unnecessary.

-        userStore.setUserInfo(userInfo);

70-76: Consider surfacing login errors to users.

Wrap loginApi/Promise.all in try/catch and show notification.error on failure.

apps/web-tdesign/src/router/guard.ts (1)

31-40: Stop progress on navigation errors too.

Add router.onError to avoid a stuck progress bar on aborted/failed navigations.

   router.afterEach((to) => {
     // 记录页面是否加载...
     loadedPaths.add(to.path);
     if (preferences.transition.progress) {
       stopProgress();
     }
   });
+
+  // Ensure progress stops on errors
+  router.onError(() => {
+    if (preferences.transition.progress) {
+      stopProgress();
+    }
+  });
apps/web-tdesign/src/adapter/vxe-table.ts (2)

7-7: UI consistency: importing ant-design-vue in a TDesign app.

To avoid mixed component libraries and styling, prefer TDesign equivalents (tdesign-vue-next) or wrap via common-ui.

-import { Button, Image } from 'ant-design-vue';
+// Prefer TDesign in apps/web-tdesign
+// import { Button, Image } from 'tdesign-vue-next'
+// or expose link/image via @vben/common-ui wrappers

43-47: Defensive: skip rendering when cell image src is empty.

-      renderTableDefault(_renderOpts, params) {
-        const { column, row } = params;
-        return h(Image, { src: row[column.field] });
-      },
+      renderTableDefault(_renderOpts, params) {
+        const { column, row } = params;
+        const src = row?.[column.field as string];
+        return src ? h(Image, { src }) : null;
+      },
apps/web-tdesign/src/views/dashboard/workspace/index.vue (1)

31-215: Replace hardcoded sample data with dynamic API calls or configuration.

The workspace view contains extensive hardcoded sample data for projects, quick navigation, todos, and trends. While acceptable for initial development, consider:

  • Fetching dynamic data from backend APIs for production use
  • Moving static navigation items to a configuration file
  • Implementing proper data models and state management for todo items
apps/web-tdesign/src/adapter/component/index.ts (1)

37-42: Remove or uncomment dead code for InputPassword and Mentions.

Lines 37-42 have commented-out imports for InputPassword and Mentions, and lines 112-113 have their corresponding commented-out types. Either complete the implementation or remove the dead code to improve maintainability.

Also applies to: 112-113

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03ce030 and 2264eaa.

⛔ Files ignored due to path filters (1)
  • apps/web-tdesign/public/favicon.ico is excluded by !**/*.ico
📒 Files selected for processing (76)
  • apps/backend-mock/utils/mock-data.ts (3 hunks)
  • apps/web-tdesign/.env (1 hunks)
  • apps/web-tdesign/.env.analyze (1 hunks)
  • apps/web-tdesign/.env.development (1 hunks)
  • apps/web-tdesign/.env.production (1 hunks)
  • apps/web-tdesign/index.html (1 hunks)
  • apps/web-tdesign/package.json (1 hunks)
  • apps/web-tdesign/postcss.config.mjs (1 hunks)
  • apps/web-tdesign/src/adapter/component/index.ts (1 hunks)
  • apps/web-tdesign/src/adapter/form.ts (1 hunks)
  • apps/web-tdesign/src/adapter/vxe-table.ts (1 hunks)
  • apps/web-tdesign/src/api/core/auth.ts (1 hunks)
  • apps/web-tdesign/src/api/core/index.ts (1 hunks)
  • apps/web-tdesign/src/api/core/menu.ts (1 hunks)
  • apps/web-tdesign/src/api/core/user.ts (1 hunks)
  • apps/web-tdesign/src/api/index.ts (1 hunks)
  • apps/web-tdesign/src/api/request.ts (1 hunks)
  • apps/web-tdesign/src/app.vue (1 hunks)
  • apps/web-tdesign/src/bootstrap.ts (1 hunks)
  • apps/web-tdesign/src/layouts/auth.vue (1 hunks)
  • apps/web-tdesign/src/layouts/basic.vue (1 hunks)
  • apps/web-tdesign/src/layouts/index.ts (1 hunks)
  • apps/web-tdesign/src/locales/README.md (1 hunks)
  • apps/web-tdesign/src/locales/index.ts (1 hunks)
  • apps/web-tdesign/src/locales/langs/en-US/demos.json (1 hunks)
  • apps/web-tdesign/src/locales/langs/en-US/page.json (1 hunks)
  • apps/web-tdesign/src/locales/langs/zh-CN/demos.json (1 hunks)
  • apps/web-tdesign/src/locales/langs/zh-CN/page.json (1 hunks)
  • apps/web-tdesign/src/main.ts (1 hunks)
  • apps/web-tdesign/src/preferences.ts (1 hunks)
  • apps/web-tdesign/src/router/access.ts (1 hunks)
  • apps/web-tdesign/src/router/guard.ts (1 hunks)
  • apps/web-tdesign/src/router/index.ts (1 hunks)
  • apps/web-tdesign/src/router/routes/core.ts (1 hunks)
  • apps/web-tdesign/src/router/routes/index.ts (1 hunks)
  • apps/web-tdesign/src/router/routes/modules/dashboard.ts (1 hunks)
  • apps/web-tdesign/src/router/routes/modules/demos.ts (1 hunks)
  • apps/web-tdesign/src/router/routes/modules/vben.ts (1 hunks)
  • apps/web-tdesign/src/store/auth.ts (1 hunks)
  • apps/web-tdesign/src/store/index.ts (1 hunks)
  • apps/web-tdesign/src/views/_core/README.md (1 hunks)
  • apps/web-tdesign/src/views/_core/about/index.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/authentication/code-login.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/authentication/forget-password.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/authentication/login.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/authentication/qrcode-login.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/authentication/register.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/fallback/coming-soon.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/fallback/forbidden.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/fallback/internal-error.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/fallback/not-found.vue (1 hunks)
  • apps/web-tdesign/src/views/_core/fallback/offline.vue (1 hunks)
  • apps/web-tdesign/src/views/dashboard/analytics/analytics-trends.vue (1 hunks)
  • apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-data.vue (1 hunks)
  • apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue (1 hunks)
  • apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-source.vue (1 hunks)
  • apps/web-tdesign/src/views/dashboard/analytics/analytics-visits.vue (1 hunks)
  • apps/web-tdesign/src/views/dashboard/analytics/index.vue (1 hunks)
  • apps/web-tdesign/src/views/dashboard/workspace/index.vue (1 hunks)
  • apps/web-tdesign/src/views/demos/antd/index.vue (1 hunks)
  • apps/web-tdesign/tailwind.config.mjs (1 hunks)
  • apps/web-tdesign/tsconfig.json (1 hunks)
  • apps/web-tdesign/tsconfig.node.json (1 hunks)
  • apps/web-tdesign/vite.config.mts (1 hunks)
  • packages/@core/base/design/src/css/ui.css (5 hunks)
  • packages/@core/ui-kit/layout-ui/src/vben-layout.vue (2 hunks)
  • packages/@core/ui-kit/popup-ui/src/modal/modal.vue (3 hunks)
  • packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/Checkbox.vue (1 hunks)
  • packages/@core/ui-kit/shadcn-ui/src/ui/input/Input.vue (1 hunks)
  • packages/@core/ui-kit/shadcn-ui/src/ui/tabs/TabsList.vue (1 hunks)
  • packages/effects/layouts/src/authentication/authentication.vue (4 hunks)
  • packages/effects/layouts/src/authentication/form.vue (2 hunks)
  • packages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vue (2 hunks)
  • packages/effects/layouts/src/widgets/lock-screen/lock-screen.vue (2 hunks)
  • playground/src/locales/langs/zh-CN/system.json (2 hunks)
  • playground/src/views/examples/layout/col-page.vue (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (17)
apps/web-tdesign/src/router/guard.ts (4)
packages/stores/src/modules/access.ts (1)
  • useAccessStore (51-123)
packages/stores/src/modules/user.ts (1)
  • useUserStore (41-58)
apps/web-tdesign/src/store/auth.ts (1)
  • useAuthStore (16-117)
packages/constants/src/core.ts (1)
  • LOGIN_PATH (4-4)
apps/web-tdesign/src/router/index.ts (1)
packages/utils/src/helpers/reset-routes.ts (1)
  • resetStaticRoutes (8-31)
apps/web-tdesign/src/api/core/menu.ts (2)
apps/web-tdesign/src/api/request.ts (1)
  • requestClient (109-111)
packages/@core/base/typings/src/vue-router.d.ts (1)
  • RouteRecordStringComponent (152-152)
apps/web-tdesign/src/adapter/component/index.ts (2)
packages/@core/base/typings/src/helper.d.ts (1)
  • Recordable (130-130)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (102-102)
apps/web-tdesign/src/router/access.ts (5)
packages/@core/base/typings/src/vue-router.d.ts (2)
  • GenerateMenuAndRoutesOptions (149-149)
  • ComponentRecordType (148-148)
packages/effects/access/src/accessible.ts (1)
  • generateAccessible (156-156)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (102-102)
apps/web-tdesign/src/api/core/menu.ts (1)
  • getAllMenusApi (8-10)
apps/web-naive/src/router/access.ts (1)
  • generateAccess (16-38)
apps/web-tdesign/src/main.ts (3)
packages/@core/preferences/src/preferences.ts (1)
  • initPreferences (61-87)
apps/web-tdesign/src/preferences.ts (1)
  • overridesPreferences (8-13)
packages/utils/src/helpers/unmount-global-loading.ts (1)
  • unmountGlobalLoading (8-31)
apps/web-tdesign/src/api/core/user.ts (2)
apps/web-tdesign/src/api/request.ts (1)
  • requestClient (109-111)
apps/backend-mock/utils/mock-data.ts (1)
  • UserInfo (1-8)
apps/web-tdesign/src/api/request.ts (5)
packages/effects/hooks/src/use-app-config.ts (1)
  • useAppConfig (9-36)
packages/stores/src/modules/access.ts (1)
  • useAccessStore (51-123)
apps/web-tdesign/src/store/auth.ts (1)
  • useAuthStore (16-117)
apps/web-tdesign/src/api/core/auth.ts (1)
  • refreshTokenApi (31-35)
packages/effects/request/src/request-client/preset-interceptors.ts (3)
  • defaultResponseInterceptor (9-45)
  • authenticateResponseInterceptor (47-110)
  • errorMessageResponseInterceptor (112-165)
apps/web-tdesign/src/router/routes/modules/demos.ts (3)
apps/web-tdesign/src/router/routes/index.ts (1)
  • routes (37-37)
packages/@core/base/typings/src/vue-router.d.ts (1)
  • RouteRecordRaw (151-151)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (102-102)
apps/web-tdesign/src/router/routes/modules/vben.ts (4)
packages/@core/base/typings/src/vue-router.d.ts (1)
  • RouteRecordRaw (151-151)
packages/@core/base/shared/src/constants/vben.ts (5)
  • VBEN_LOGO_URL (14-15)
  • VBEN_DOC_URL (9-9)
  • VBEN_GITHUB_URL (4-4)
  • VBEN_NAIVE_PREVIEW_URL (24-24)
  • VBEN_ELE_PREVIEW_URL (22-22)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (102-102)
apps/web-tdesign/src/layouts/index.ts (1)
  • IFrameView (6-6)
apps/web-tdesign/src/store/auth.ts (7)
packages/stores/src/modules/access.ts (1)
  • useAccessStore (51-123)
packages/stores/src/modules/user.ts (1)
  • useUserStore (41-58)
apps/backend-mock/utils/mock-data.ts (1)
  • UserInfo (1-8)
apps/web-tdesign/src/api/core/auth.ts (3)
  • loginApi (24-26)
  • getAccessCodesApi (49-51)
  • logoutApi (40-44)
packages/stores/src/setup.ts (1)
  • resetAllStores (51-60)
packages/constants/src/core.ts (1)
  • LOGIN_PATH (4-4)
apps/web-tdesign/src/api/core/user.ts (1)
  • getUserInfoApi (8-10)
apps/web-tdesign/src/router/routes/index.ts (2)
packages/@core/base/typings/src/vue-router.d.ts (1)
  • RouteRecordRaw (151-151)
apps/web-tdesign/src/router/routes/core.ts (2)
  • coreRoutes (97-97)
  • fallbackNotFoundRoute (97-97)
apps/web-tdesign/src/api/core/auth.ts (1)
apps/web-tdesign/src/api/request.ts (2)
  • requestClient (109-111)
  • baseRequestClient (113-113)
apps/web-tdesign/src/router/routes/modules/dashboard.ts (3)
apps/web-tdesign/src/router/routes/index.ts (1)
  • routes (37-37)
packages/@core/base/typings/src/vue-router.d.ts (1)
  • RouteRecordRaw (151-151)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (102-102)
apps/web-tdesign/src/adapter/form.ts (1)
apps/web-tdesign/src/adapter/component/index.ts (1)
  • ComponentType (100-126)
apps/web-tdesign/src/router/routes/core.ts (2)
packages/constants/src/core.ts (1)
  • LOGIN_PATH (4-4)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (102-102)
apps/web-tdesign/src/bootstrap.ts (4)
packages/effects/common-ui/src/components/loading/directive.ts (1)
  • registerLoadingDirective (107-132)
packages/stores/src/setup.ts (1)
  • initStores (20-49)
packages/effects/access/src/directive.ts (1)
  • registerAccessDirective (40-42)
packages/effects/common-ui/src/components/tippy/index.ts (1)
  • initTippy (34-48)
🪛 Biome (2.1.2)
apps/web-tdesign/package.json

[error] 49-50: Expected a property but instead found '}'.

Expected a property here.

(parse)

apps/web-tdesign/src/store/auth.ts

[error] 50-50: Can't assign userInfo because it's a constant.

This is where the variable is defined as constant.

Unsafe fix: Replace const with let if you assign it to a new value.

(lint/correctness/noConstAssign)

🪛 dotenv-linter (4.0.0)
apps/web-tdesign/.env

[warning] 2-2: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)

🪛 GitHub Actions: Build detection
apps/web-tdesign/package.json

[error] 50-50: pnpm install --frozen-lockfile failed. ERR_PNPM_JSON_PARSE: Expected double-quoted property name in JSON at position 1428 (line 50 column 1) while parsing '/home/runner/work/vue-vben-admin/vue-vben-admin/apps/web-tdesign/package.json'.

🪛 GitHub Actions: CI
apps/web-tdesign/package.json

[error] 50-50: PNPM JSON parse failed. Expected double-quoted property name in JSON at position 1428 (line 50 column 1) while parsing '{ "name": "@vben/web-tdesign", "vers' in /home/runner/work/vue-vben-admin/vue-vben-admin/apps/web-tdesign/package.json. Process completed with exit code 1.

🔇 Additional comments (71)
packages/@core/base/design/src/css/ui.css (1)

1-4: Verify intentionality and test coverage for significant animation timing and distance changes.

The animation updates represent substantial visual changes: 50% increase in duration (0.2s → 0.3s) and 5× larger initial transform distances (±10px → ±50px). These are breaking changes in animation behavior that will visually differ across the UI.

Please confirm:

  1. These changes align with the TD-Design visual specifications.
  2. Animation behavior has been tested against components that rely on .side-content.
  3. The new 0.3s timing and ±50px distances are intentional and improve UX (not regressions).
packages/@core/ui-kit/shadcn-ui/src/ui/tabs/TabsList.vue (1)

24-24: Border radius styling adjustment looks good.

The change from rounded-lg to rounded-md reduces the corner radius slightly. This appears intentional, likely aligning with design system updates.

Please confirm this styling change is intentional and consistent with other tab-related components across the UI kit.

apps/web-tdesign/package.json (1)

46-46: Verify tdesign-vue-next version compatibility.

The package pins tdesign-vue-next to ^1.17.1. Ensure this version is compatible with the Vue version and other dependencies defined in this package. Consider aligning with any workspace-level version constraints if they exist.

apps/backend-mock/utils/mock-data.ts (1)

279-297: LGTM! Correct parent-child relationship fixed.

The pid correction from 201 to 202 for the SystemDept button entries (Create, Edit, Delete) is a bug fix that properly nests these operations under the SystemDept menu (id 202) instead of the SystemMenu (id 201). This aligns with the logical menu hierarchy and the button ID naming convention (20_4xx for dept operations vs 20_1xx for menu operations).

playground/src/locales/langs/zh-CN/system.json (1)

2-2: LGTM! JSON structure cleanup.

Relocating the root-level title to the top and removing the duplicate improves the JSON structure and readability with no functional impact on translations.

Also applies to: 66-66

packages/effects/layouts/src/widgets/lock-screen/lock-screen.vue (1)

40-40: LGTM! API enhancement for field component access.

The addition of getFieldComponentRef to the form controller API enables programmatic access to field components, which supports the new auto-focus behavior below.

packages/effects/layouts/src/widgets/lock-screen/lock-screen-modal.vue (1)

30-53: LGTM! Form controller API correctly expanded.

The form setup is clean and the addition of getFieldComponentRef aligns with the auto-focus enhancement implemented in the onOpened hook below.

packages/@core/ui-kit/popup-ui/src/modal/modal.vue (2)

183-187: LGTM! Typo fix improves code consistency.

The function name correction from handerOpenAutoFocus to handleOpenAutoFocus fixes a typo and aligns with standard naming conventions.


212-216: Verify the design rationale for requestAnimationFrame in handleOpened and alignment with handleClosed.

The handleOpened function (lines 212–216) defers the callback using requestAnimationFrame, while handleClosed (lines 218–220) executes its callback immediately. This inconsistency is the only instance of requestAnimationFrame in the popup-ui component.

Verify:

  1. Is the deferred execution necessary for onOpened (e.g., waiting for DOM paint/layout)?
  2. Why handleClosed does not require the same pattern?
  3. Could rapid open/close cycles cause onOpened to fire after the modal is already closed?

If this asymmetry is intentional, add a comment explaining the rationale. If not, align both handlers for consistency.

packages/effects/layouts/src/authentication/form.vue (2)

5-8: LGTM! Clean prop definition with proper typing.

The new dataSide prop is well-typed and optional, enabling panel-aware styling while maintaining backward compatibility.


23-24: LGTM! Improved semantics and proper prop binding.

The class rename to side-content is more semantic, and the :data-side binding correctly wires the prop to enable position-aware styling.

packages/effects/layouts/src/authentication/authentication.vue (4)

53-53: LGTM! Consistent panel position identification.

The data-side="left" attribute correctly identifies the left panel position for styling/animation purposes.


120-120: LGTM! Center panel correctly identified.

The data-side="bottom" attribute appropriately identifies the center panel position for bottom-up animations.


136-137: LGTM! Symmetrical width and consistent panel identification.

The width change from w-[34%] to w-2/5 creates symmetry with the left panel, and data-side="right" correctly identifies the panel position.


89-96: Panel state flags are guaranteed mutually exclusive.

The computed properties authPanelLeft, authPanelRight, and authPanelCenter derive from a single source of truth (appPreferences.value.authPageLayout), ensuring only one can be true at any time. The animation logic is correct as implemented.

apps/web-tdesign/tailwind.config.mjs (1)

1-1: LGTM! Clean configuration delegation.

The re-export pattern is consistent with the PostCSS configuration and follows monorepo best practices for sharing common configurations.

apps/web-tdesign/postcss.config.mjs (1)

1-1: ✓ Dependency verified and correctly configured.

The @vben/tailwind-config package is properly declared in the root package.json with "workspace:*" protocol, and the ./postcss subpath export is correctly defined in its package.json. The source file exists at internal/tailwind-config/src/postcss.config.ts. This is a correct pattern for a pnpm monorepo shared configuration.

packages/@core/ui-kit/layout-ui/src/vben-layout.vue (2)

13-13: LGTM!

The import change from Menu to IconifyIcon is appropriate for the conditional icon rendering implemented below.


562-563: Icon verification complete—no issues found.

Both ep:fold and ep:expand are valid icons in the Element Plus/Iconify library. The codebase search confirms these icons are used only at the specified lines in vben-layout.vue, and the icon logic is semantically correct.

apps/web-tdesign/src/views/_core/README.md (1)

1-3: LGTM! Documentation is clear and appropriate.

The README provides a concise description of the core views directory purpose, which aligns with the application structure introduced in this PR.

apps/web-tdesign/.env.analyze (1)

1-7: LGTM! Environment configuration is appropriate.

The environment variables are standard for build analysis mode, with visualizer enabled and API proxy configured correctly.

apps/web-tdesign/src/views/_core/fallback/coming-soon.vue (1)

1-7: LGTM! Component follows established patterns.

The coming-soon fallback view is consistent with other fallback components in the app, correctly delegating to the reusable Fallback component from @vben/common-ui.

apps/web-tdesign/tsconfig.node.json (1)

1-10: LGTM! TypeScript configuration is correct.

The node TypeScript configuration properly sets up composite builds with project references, which enables incremental compilation and better build performance.

apps/web-tdesign/tsconfig.json (1)

1-12: LGTM! TypeScript configuration is well-structured.

The application TypeScript configuration correctly sets up:

  • Path aliases for convenient imports
  • Project references for build coordination
  • Appropriate file inclusion patterns for Vue and TypeScript
apps/web-tdesign/src/locales/README.md (1)

3-3: No issue found: the mention of Ant Design components is accurate for this app.

Based on verification, the app extensively uses Ant Design Vue components (10+ imports confirmed across multiple files including app.vue, locales/index.ts, store/auth.ts, router/access.ts, and adapters). The documentation's reference to "antd组件库" is factually correct and not a copy-paste oversight. While the app naming ("web-tdesign") may be misleading, the component library reference in the README is appropriate for the codebase.

apps/web-tdesign/src/locales/langs/zh-CN/demos.json (1)

1-12: No changes required—translations are intentional.

The localization file correctly reflects the app's architecture: demos.antd references a local Ant Design demo component (#/views/demos/antd/index.vue), while demos.vben.naive-ui and demos.vben.element-plus label external preview links that showcase Vben instances with different UI frameworks. All entries are actively used in the router configuration and serve the app's purpose as a multi-framework demo hub.

packages/@core/ui-kit/shadcn-ui/src/ui/input/Input.vue (1)

27-27: Placeholder contrast concern is valid but requires manual verification.

The Input component is actively used in the codebase:

  • packages/@core/ui-kit/popup-ui/src/alert/AlertBuilder.ts imports it
  • packages/effects/layouts/src/widgets/preferences/blocks/input-item.vue imports it
  • packages/@core/ui-kit/shadcn-ui/src/components/input-password/input-password.vue imports it

The muted-foreground color uses CSS custom properties (hsl(var(--muted-foreground))), so actual color values are theme-dependent and cannot be verified computationally. The 50% opacity modifier on the placeholder could impact contrast ratios depending on the theme's muted-foreground and input background colors.

The original recommendation for visual testing across various background colors and theme combinations is appropriate and necessary before merging.

apps/web-tdesign/src/views/_core/fallback/internal-error.vue (1)

1-9: LGTM!

Clean implementation following the established fallback component pattern. The component correctly wraps the Fallback component with status 500 for internal server error scenarios.

apps/web-tdesign/src/views/_core/authentication/qrcode-login.vue (1)

1-10: LGTM!

The component correctly wraps the AuthenticationQrCodeLogin component and properly binds the LOGIN_PATH constant for navigation. Implementation is clean and follows Vue 3 composition API best practices.

playground/src/views/examples/layout/col-page.vue (2)

25-26: LGTM!

Enabling splitHandle and splitLine provides better UX for the resizable layout feature by showing visual indicators for the drag interaction.


45-49: LGTM!

The addition of flex items-center justify-center classes properly centers the expand icon within the circular button, improving the visual alignment in the collapsed state.

apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-data.vue (1)

1-82: LGTM!

The radar chart implementation correctly uses the Echarts integration pattern. The hardcoded demo data is appropriate for an initial dashboard visualization component.

apps/web-tdesign/src/views/_core/fallback/offline.vue (1)

1-9: LGTM!

Clean implementation following the established fallback component pattern for offline status scenarios.

apps/web-tdesign/src/views/_core/authentication/code-login.vue (1)

24-29: Verify phone number validation for internationalization.

The mobile validation uses a hardcoded 11-digit regex pattern (/^\d{11}$/), which is specific to Chinese phone numbers. Ensure this aligns with your internationalization requirements.

If the app needs to support international phone numbers, consider using a more flexible validation approach or a library like libphonenumber-js.

apps/web-tdesign/src/store/index.ts (1)

1-1: LGTM!

Clean barrel export following standard module pattern, enabling consumers to import authentication store functionality from the store root.

apps/web-tdesign/src/layouts/auth.vue (1)

1-23: LGTM! Clean authentication layout implementation.

The component correctly uses computed properties for reactive preference bindings and properly integrates localization. The commented toolbar slot provides a clear extension point for future customization.

packages/@core/ui-kit/shadcn-ui/src/ui/checkbox/Checkbox.vue (1)

34-34: LGTM! Good hover state addition.

The hover:border-primary class enhances the interactive feedback for the checkbox component, improving the user experience.

apps/web-tdesign/src/api/index.ts (1)

1-1: LGTM! Standard barrel export pattern.

The re-export provides a clean public API surface for the core modules.

apps/web-tdesign/src/layouts/index.ts (1)

1-6: LGTM! Proper lazy loading implementation.

The lazy-loaded exports enable code splitting and optimize initial bundle size, which is good for performance.

apps/web-tdesign/src/api/core/user.ts (1)

1-10: LGTM! Clean API wrapper implementation.

The function is well-typed, properly documented, and follows the project's API patterns.

apps/web-tdesign/src/views/_core/fallback/not-found.vue (1)

1-9: LGTM! Clean 404 fallback component.

The component properly uses the shared Fallback UI component with the 404 status. Simple and correct implementation.

apps/web-tdesign/src/locales/langs/en-US/demos.json (1)

1-12: LGTM!

The locale structure and translations are clean and well-organized.

apps/web-tdesign/.env.development (1)

1-16: LGTM!

Development environment configuration is appropriate with sensible defaults for local development.

apps/web-tdesign/src/api/core/index.ts (1)

1-3: LGTM!

Clean barrel export pattern for the core API modules.

apps/web-tdesign/src/adapter/form.ts (1)

11-42: Well-structured form adapter initialization.

The form adapter properly configures model prop names for different component types and provides internationalized validation rules.

apps/web-tdesign/src/api/core/menu.ts (1)

5-10: LGTM!

Clean API helper implementation. Error handling is appropriately delegated to the centralized requestClient.

apps/web-tdesign/src/views/_core/about/index.vue (1)

1-9: LGTM!

Clean and straightforward wrapper component for the About page.

apps/web-tdesign/src/views/dashboard/analytics/analytics-visits-sales.vue (1)

11-41: Well-configured ECharts visualization.

The pie chart setup with animations, color palette, and rose-type radius creates an engaging data visualization.

apps/web-tdesign/.env.production (1)

3-4: ****

The production configuration using the mock API endpoint is intentional and documented behavior. The official documentation explicitly configures .env.production with VITE_GLOB_API_URL=https://mock-napi.vben.pro/api.

The project design allows developers to dynamically modify the API endpoint in dist/_app.config.js after building without needing to rebuild for different environments. This is a template/demo project where the mock API serves as the default example configuration—developers are expected to modify it post-deployment as needed.

Likely an incorrect or invalid review comment.

apps/web-tdesign/vite.config.mts (2)

1-5: LGTM!

The configuration structure is appropriate for a new app setup, and the empty application object serves as a valid placeholder for future configuration.


9-15: Proxy configuration is correct and intentional.

The double /api pattern you questioned is the correct design. The mock server serves at http://localhost:5320/api, and the proxy correctly rewrites requests to reach that endpoint. The request flow /api/users/usershttp://localhost:5320/api/users is intentional.

This pattern is consistently used across all four web applications (web-antd, web-ele, web-naive, and web-tdesign), confirming it's the standard approach in this codebase.

apps/web-tdesign/src/views/_core/fallback/forbidden.vue (1)

1-9: LGTM!

The 403 fallback component is correctly implemented using the common Fallback component from @vben/common-ui. The structure is clean and appropriate for an error fallback view.

apps/web-tdesign/src/router/access.ts (1)

17-40: Access generation logic is well-structured.

The generateAccess function correctly builds the page and layout maps, integrates with the access system, and properly handles the forbidden component and menu fetching flow. The structure aligns with the established pattern.

apps/web-tdesign/src/locales/langs/en-US/page.json (1)

1-14: LGTM!

The English locale file is well-structured with appropriate translations for authentication and dashboard pages. The JSON structure is valid and the key naming is consistent.

apps/web-tdesign/index.html (1)

30-35: LGTM!

The body structure is standard and correctly configured with the app mount point and module script entry.

apps/web-tdesign/src/router/routes/modules/dashboard.ts (1)

1-38: LGTM!

The dashboard routes are well-structured with proper dynamic imports, localized titles, and appropriate metadata. The affixed Analytics tab provides a good default dashboard experience.

apps/web-tdesign/src/preferences.ts (1)

1-13: LGTM!

The preferences configuration is clean and correctly uses the environment variable for the app name. The comments provide helpful context about the override behavior and cache considerations.

apps/web-tdesign/src/router/routes/index.ts (1)

1-37: LGTM!

The router index effectively aggregates routes from multiple sources using dynamic imports and provides a clear separation between core, access-controlled, and external routes. The structure is extensible and follows best practices.

apps/web-tdesign/src/views/demos/antd/index.vue (1)

1-66: LGTM! Well-structured demo component.

The Ant Design Vue integration demo is well-organized with clear examples of buttons, messages, and notifications. The component properly demonstrates UI framework integration patterns.

apps/web-tdesign/src/main.ts (1)

1-31: LGTM! Clean bootstrap initialization flow.

The asynchronous initialization properly sequences preferences setup, dynamic bootstrap import, and loading cleanup. The namespace computation ensures proper isolation across environments and versions.

apps/web-tdesign/src/app.vue (1)

1-39: LGTM! Proper theme integration.

The App component correctly integrates Ant Design Vue's ConfigProvider with dynamic theme computation based on user preferences. The reactive token theme properly handles dark mode and compact algorithm switches.

apps/web-tdesign/src/bootstrap.ts (1)

1-78: Well-structured bootstrap sequence.

The bootstrap function properly orchestrates app initialization with a clear sequence: component adapters, form setup, directives, internationalization, stores, routing, and plugins. The dynamic title management with watchEffect is a nice touch.

apps/web-tdesign/src/views/_core/authentication/login.vue (1)

1-99: LGTM! Well-implemented login form.

The login component uses a clean schema-driven approach with proper validation and user-friendly auto-fill behavior. The integration with the auth store and the use of mock users for development is appropriate.

apps/web-tdesign/src/router/routes/core.ts (1)

1-97: LGTM! Well-organized route structure.

The core routes are properly structured with clear separation between basic and authentication layouts. Dynamic imports enable code splitting, and localized route titles integrate well with the i18n system.

apps/web-tdesign/src/layouts/basic.vue (1)

109-127: Confirm preferences reactivity in watch source.

If preferences.app.* are not reactive refs, this watch won’t re-run after changes. If needed, switch to watchEffect or watch explicit reactive refs.

apps/web-tdesign/src/router/guard.ts (1)

110-117: Double-check redirect source after access generation.

Using from.query.redirect works when coming from /auth/login, but other flows may carry redirect on to.query. Consider preferring to.query.redirect with fallback to from.query.redirect.

-    const redirectPath = (from.query.redirect ??
+    const redirectPath = (to.query.redirect ?? from.query.redirect ??
       (to.path === preferences.app.defaultHomePath
         ? userInfo.homePath || preferences.app.defaultHomePath
         : to.fullPath)) as string;
apps/web-tdesign/src/adapter/vxe-table.ts (1)

25-34: Verify proxy response mapping matches your backend and vxe-table expectations.

result and list both pointing to 'items' may be redundant depending on your adapter. Please confirm against @vben/plugins/vxe-table/vxe docs.

apps/web-tdesign/src/views/dashboard/workspace/index.vue (1)

221-233: LGTM! Navigation logic is well-structured.

The navTo function correctly handles both external URLs and internal routes with appropriate error handling and user feedback.

apps/web-tdesign/src/api/request.ts (2)

64-72: LGTM! Request interceptor properly injects authentication and locale headers.

The interceptor correctly adds the Authorization header with the formatted token and sets the Accept-Language header from preferences.


75-92: LGTM! Response interceptors are well-configured for authentication flow.

The interceptor chain properly handles:

  • Data extraction via defaultResponseInterceptor with appropriate field mappings
  • Token refresh logic via authenticateResponseInterceptor with 401 handling
apps/web-tdesign/src/adapter/component/index.ts (1)

128-210: LGTM! Component adapter initialization is well-structured.

The initComponentAdapter function properly:

  • Registers TDesign components with appropriate placeholder handling
  • Uses the withDefaultPlaceholder HOC for consistent UX
  • Configures API components with correct prop mappings
  • Registers components in global shared state

Comment on lines +57 to +60
async function handleLogin(values: Recordable<any>) {
// eslint-disable-next-line no-console
console.log(values);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Complete the login implementation.

The handleLogin function currently only logs the form values to the console without performing any actual authentication. This needs to be implemented with proper API calls, state management, and error handling.

Do you want me to generate a proper implementation that integrates with the authentication store and API, similar to other authentication views in the codebase?

🤖 Prompt for AI Agents
In apps/web-tdesign/src/views/_core/authentication/code-login.vue around lines
57 to 60, the handleLogin function only logs the form values; replace it with a
real login flow: call the authentication API (await authApi.login(values) or the
project-equivalent), wrap the call in try/catch to handle and surface errors,
set a loading state during the request, store the returned token/user in the
authentication store (commit or dispatch the existing auth store action),
persist token if required, and navigate to the post-login route on success;
ensure you display success/error messages to the user and clear loading in
finally.

Comment on lines +56 to +63
// xAxis: {
// axisTick: {
// show: false,
// },
// boundaryGap: false,
// data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
// type: 'category',
// },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Remove commented-out code.

The commented xAxis configuration (Lines 56-63) is redundant, as the active configuration below (Lines 64-78) contains the same settings with only the splitLine addition. Remove dead code to improve maintainability.

Apply this diff to remove the commented code:

-    // xAxis: {
-    //   axisTick: {
-    //     show: false,
-    //   },
-    //   boundaryGap: false,
-    //   data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
-    //   type: 'category',
-    // },
     xAxis: {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// xAxis: {
// axisTick: {
// show: false,
// },
// boundaryGap: false,
// data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`),
// type: 'category',
// },
xAxis: {
🤖 Prompt for AI Agents
In apps/web-tdesign/src/views/dashboard/analytics/analytics-trends.vue around
lines 56 to 63, remove the dead commented-out xAxis block (the lines beginning
with // xAxis: { through the closing // },) since an active xAxis configuration
exists below; delete those commented lines so the file no longer contains the
redundant commented configuration and keep the active xAxis block (lines 64-78)
intact.

Comment on lines +12 to +49
renderEcharts({
grid: {
bottom: 0,
containLabel: true,
left: '1%',
right: '1%',
top: '2 %',
},
series: [
{
barMaxWidth: 80,
// color: '#4f69fd',
data: [
3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000,
3200, 4800,
],
type: 'bar',
},
],
tooltip: {
axisPointer: {
lineStyle: {
// color: '#4f69fd',
width: 1,
},
},
trigger: 'axis',
},
xAxis: {
data: Array.from({ length: 12 }).map((_item, index) => `${index + 1}月`),
type: 'category',
},
yAxis: {
max: 8000,
splitNumber: 4,
type: 'value',
},
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Fix chart data/axis mismatch and grid.top spacing.

Series has 13 points but xAxis has 12 labels; also '2 %' should be '2%'.

     grid: {
       bottom: 0,
       containLabel: true,
       left: '1%',
       right: '1%',
-      top: '2 %',
+      top: '2%',
     },
     series: [
       {
         barMaxWidth: 80,
         // color: '#4f69fd',
-        data: [
-          3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000,
-          3200, 4800,
-        ],
+        data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200],
         type: 'bar',
       },
     ],
     ...
     xAxis: {
-      data: Array.from({ length: 12 }).map((_item, index) => `${index + 1}月`),
+      data: Array.from({ length: 12 }).map((_item, index) => `${index + 1}月`),
       type: 'category',
     },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
renderEcharts({
grid: {
bottom: 0,
containLabel: true,
left: '1%',
right: '1%',
top: '2 %',
},
series: [
{
barMaxWidth: 80,
// color: '#4f69fd',
data: [
3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000,
3200, 4800,
],
type: 'bar',
},
],
tooltip: {
axisPointer: {
lineStyle: {
// color: '#4f69fd',
width: 1,
},
},
trigger: 'axis',
},
xAxis: {
data: Array.from({ length: 12 }).map((_item, index) => `${index + 1}月`),
type: 'category',
},
yAxis: {
max: 8000,
splitNumber: 4,
type: 'value',
},
});
renderEcharts({
grid: {
bottom: 0,
containLabel: true,
left: '1%',
right: '1%',
top: '2%',
},
series: [
{
barMaxWidth: 80,
// color: '#4f69fd',
data: [3000, 2000, 3333, 5000, 3200, 4200, 3200, 2100, 3000, 5100, 6000, 3200],
type: 'bar',
},
],
tooltip: {
axisPointer: {
lineStyle: {
// color: '#4f69fd',
width: 1,
},
},
trigger: 'axis',
},
xAxis: {
data: Array.from({ length: 12 }).map((_item, index) => `${index + 1}月`),
type: 'category',
},
yAxis: {
max: 8000,
splitNumber: 4,
type: 'value',
},
});
🤖 Prompt for AI Agents
In apps/web-tdesign/src/views/dashboard/analytics/analytics-visits.vue around
lines 12 to 49, the series data array contains 13 values while xAxis generates
12 labels and the grid.top string has an extra space ("2 %"); make the series
and xAxis lengths match by either removing one value from the data array to make
it 12 items or changing xAxis to generate 13 labels (Array.from({ length: 13
})), and fix the grid.top value to "2%". Ensure after the change the chart data
indices align and the grid.top string has no extra spaces.

Comment on lines +85 to +87
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问来源">
<AnalyticsVisitsSales />
</AnalysisChartCard>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Duplicate title for the third chart card.

The third AnalysisChartCard has the same title "访问来源" as the second card (Line 82). Based on the component AnalyticsVisitsSales, this should likely have a distinct title such as "访问销售" or "销售数据".

Apply this diff to fix the title:

-      <AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问来源">
+      <AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问销售">
         <AnalyticsVisitsSales />
       </AnalysisChartCard>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问来源">
<AnalyticsVisitsSales />
</AnalysisChartCard>
<AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问销售">
<AnalyticsVisitsSales />
</AnalysisChartCard>
🤖 Prompt for AI Agents
In apps/web-tdesign/src/views/dashboard/analytics/index.vue around lines 85 to
87, the third AnalysisChartCard incorrectly reuses the title "访问来源"; update the
title to a distinct one matching the AnalyticsVisitsSales component (for example
change title="访问来源" to title="访问销售" or title="销售数据") so the card accurately
reflects sales data.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
apps/web-tdesign/src/adapter/component/index.ts (1)

11-11: Inconsistent UI library: using Ant Design Vue in a TDesign application.

This file imports and uses notification from ant-design-vue despite this being a TDesign-based application. This creates an unnecessary dependency and UI inconsistency.

Replace with TDesign's notification:

-import { notification } from 'ant-design-vue';
+import { NotifyPlugin } from 'tdesign-vue-next';

Then update the usage:

     copyPreferencesSuccess: (title, content) => {
-      notification.success({
-        description: content,
-        message: title,
-        placement: 'bottomRight',
+      NotifyPlugin.success({
+        title,
+        content,
+        placement: 'bottom-right',
       });
     },

Also applies to: 219-225

apps/web-tdesign/src/adapter/form.ts (1)

23-27: Potential runtime error: unsafe .length access in validation.

The validation logic checks value.length === 0 without first verifying that value has a length property. This will throw a runtime error if the value is a number, boolean, object, or other type without a length property.

Apply this diff to make the validation more robust:

       required: (value, _params, ctx) => {
-        if (value === undefined || value === null || value.length === 0) {
+        if (
+          value === undefined ||
+          value === null ||
+          value === '' ||
+          (Array.isArray(value) && value.length === 0)
+        ) {
           return $t('ui.formRules.required', [ctx.label]);
         }
         return true;
       },
🧹 Nitpick comments (1)
apps/web-tdesign/.env (1)

2-2: Add quotes around the application title value.

The title has been correctly updated to reflect Tdesign (good catch on the previous feedback!), but dotenv-linter flags that the value should be quoted to follow conventions.

Apply this diff:

-VITE_APP_TITLE=Vben Admin Tdesign
+VITE_APP_TITLE="Vben Admin Tdesign"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2264eaa and 33b7a60.

📒 Files selected for processing (4)
  • apps/web-tdesign/.env (1 hunks)
  • apps/web-tdesign/src/adapter/component/index.ts (1 hunks)
  • apps/web-tdesign/src/adapter/form.ts (1 hunks)
  • apps/web-tdesign/src/app.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web-tdesign/src/app.vue
🧰 Additional context used
🧬 Code graph analysis (2)
apps/web-tdesign/src/adapter/form.ts (1)
apps/web-tdesign/src/adapter/component/index.ts (1)
  • ComponentType (101-127)
apps/web-tdesign/src/adapter/component/index.ts (2)
packages/@core/base/typings/src/helper.d.ts (1)
  • Recordable (130-130)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (102-102)
🪛 dotenv-linter (4.0.0)
apps/web-tdesign/.env

[warning] 2-2: [ValueWithoutQuotes] This value needs to be surrounded in quotes

(ValueWithoutQuotes)

🔇 Additional comments (7)
apps/web-tdesign/.env (1)

5-5: Namespace correctly updated to match Tdesign application.

This has been properly corrected from the previous vben-web-antd reference.

apps/web-tdesign/src/adapter/component/index.ts (3)

18-64: Well-structured component imports.

The use of defineAsyncComponent for lazy loading and ES module imports from tdesign-vue-next/es/* enables effective code splitting and tree-shaking.


66-98: Excellent HOC implementation with transparent ref forwarding.

The withDefaultPlaceholder higher-order component is well-designed:

  • Properly merges placeholder from props, attrs, or i18n defaults
  • Uses Proxy to transparently expose inner component methods
  • Maintains proper ref forwarding through innerRef

134-161: ApiSelect and ApiTreeSelect configurations are well-defined.

The adapter configurations properly map TDesign component props:

  • Correct loading slot (suffixIcon)
  • Appropriate visibility events
  • Proper model prop names
  • Field name mappings for TreeSelect
apps/web-tdesign/src/adapter/form.ts (3)

7-19: Model prop name mappings are correct for TDesign.

The configuration properly handles TDesign's v-model conventions:

  • Default v-model:value for most components
  • v-model:checked for Checkbox, Radio, Switch
  • v-model:fileList for Upload

30-34: selectRequired validation is correctly implemented.

Unlike the required rule, this validation appropriately only checks for null and undefined, allowing falsy values like 0 or false which may be valid selections.


40-45: Clean and well-typed exports.

The module provides a clear public API:

  • Type-safe useVbenForm hook bound to ComponentType
  • Convenient re-export of z (Zod) for validation schemas
  • Properly typed form schema and props

VITE_APP_NAMESPACE=vben-web-tdesign

# 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密
VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Critical security issue: Replace the placeholder encryption key before deployment.

The placeholder value please-replace-me-with-your-own-key remains unresolved. Per prior analysis, this key is actively used for AES encryption of localStorage data. Deploying with this placeholder would compromise the security of encrypted store data.

Before any production deployment, generate and inject a strong, randomly generated encryption key via GitHub Actions secrets or .env.local override to replace this placeholder.


I'll verify the security concern in the review comment by examining the codebase.


🏁 Script executed:

#!/bin/bash
# Step 1: Verify the file exists and contains the placeholder
echo "=== Checking for .env file ==="
fd -a "\.env$" apps/web-tdesign/

echo ""
echo "=== Content of .env file ==="
cat apps/web-tdesign/.env 2>/dev/null || echo "File not found"

echo ""
echo "=== Searching for VITE_APP_STORE_SECURE_KEY usage ==="
rg -n "VITE_APP_STORE_SECURE_KEY" --type-list | head -20

echo ""
echo "=== Searching in source code (not node_modules) ==="
rg -n "VITE_APP_STORE_SECURE_KEY" -g '!node_modules' -g '!dist' -g '!build' --type=ts --type=js --type=tsx --type=jsx -C 3

Length of output: 809


I need to correct my search syntax and locate where this key is actually used.


🏁 Script executed:

#!/bin/bash
# Fixed search for VITE_APP_STORE_SECURE_KEY usage
echo "=== Searching for VITE_APP_STORE_SECURE_KEY in source code ==="
rg -n "VITE_APP_STORE_SECURE_KEY" -g '!node_modules' -g '!dist' -g '!build' -C 4

echo ""
echo "=== Searching for encryption/crypto-related imports ==="
rg -n "encrypt|crypto|aes" -i -g '!node_modules' -g '!dist' -g '!build' -C 2 | head -80

echo ""
echo "=== Looking for store-related files ==="
fd -t f "store" apps/web-tdesign/src --extension ts --extension js | head -20

echo ""
echo "=== Checking for .env.local or similar override files ==="
fd -a "\.env" apps/web-tdesign/ -type f

Length of output: 5136


🏁 Script executed:

#!/bin/bash
# Fixed search for VITE_APP_STORE_SECURE_KEY usage
echo "=== Searching for VITE_APP_STORE_SECURE_KEY in source code ==="
rg -n "VITE_APP_STORE_SECURE_KEY" -g '!node_modules' -g '!dist' -g '!build' -C 4

echo ""
echo "=== Searching for encryption/crypto-related imports ==="
rg -n "encrypt|crypto|aes" -i -g '!node_modules' -g '!dist' -g '!build' -C 2 | head -80

echo ""
echo "=== Looking for store configuration files ==="
fd -t f store apps/web-tdesign/src --extension ts --extension js 2>/dev/null | head -20

echo ""
echo "=== Checking for .env variants ==="
fd -a "\.env" apps/web-tdesign/ -type f

Length of output: 5119


I need to check for deployment safeguards and build-time configurations.


🏁 Script executed:

#!/bin/bash
# Search for vite config and build-time security checks
echo "=== Looking for vite config files ==="
fd -t f "vite\.config" apps/web-tdesign/

echo ""
echo "=== Searching for .env validation or security checks ==="
rg -n "VITE_APP_STORE_SECURE_KEY|please-replace-me" -g '!node_modules' -g '!pnpm-lock.yaml'

echo ""
echo "=== Checking for build scripts that validate env vars ==="
rg -n "VITE_APP_STORE_SECURE_KEY" -g '!node_modules' packages/stores/

echo ""
echo "=== Checking .github workflows for secret injection ==="
fd -t f "workflow" -o "yml" -o "yaml" ".github/" 2>/dev/null

echo ""
echo "=== Looking at package.json for build commands ==="
rg -n "\"build\"|\"dev\"" apps/web-tdesign/package.json -C 2 2>/dev/null | head -30

Length of output: 776


I need to verify if this is a template project or actual production deployment, and check for environment-specific configurations.


🏁 Script executed:

#!/bin/bash
# Find all .env files and variants
echo "=== All .env files in entire repo ==="
find . -maxdepth 3 -name ".env*" -type f 2>/dev/null | grep -v node_modules

echo ""
echo "=== Check vite.config.mts content ==="
cat apps/web-tdesign/vite.config.mts | head -50

echo ""
echo "=== Search for .env.local in gitignore ==="
rg "\.env\.local" -g '.gitignore' .

echo ""
echo "=== Check README for setup instructions ==="
fd -t f README apps/web-tdesign/ -exec cat {} \; 2>/dev/null | head -60

echo ""
echo "=== Look for deployment or production documentation ==="
fd -t f "deploy|production|setup" apps/web-tdesign/ -type f 2>/dev/null | head -10

Length of output: 1273


Let me check the environment-specific configuration files to see if production has a proper value or also uses the placeholder.


🏁 Script executed:

#!/bin/bash
# Compare .env files for web-tdesign
echo "=== .env (base) ==="
cat apps/web-tdesign/.env | grep -i "VITE_APP_STORE_SECURE_KEY\|VITE_APP_TITLE\|VITE_APP_NAMESPACE"

echo ""
echo "=== .env.production ==="
cat apps/web-tdesign/.env.production | grep -i "VITE_APP_STORE_SECURE_KEY\|VITE_APP_TITLE\|VITE_APP_NAMESPACE" || echo "(no production override)"

echo ""
echo "=== .env.development ==="
cat apps/web-tdesign/.env.development | grep -i "VITE_APP_STORE_SECURE_KEY\|VITE_APP_TITLE\|VITE_APP_NAMESPACE" || echo "(no development override)"

echo ""
echo "=== Pattern check: Compare across other apps ==="
echo "web-antd .env.production:"
grep "VITE_APP_STORE_SECURE_KEY" apps/web-antd/.env.production 2>/dev/null || echo "not found"

echo ""
echo "web-ele .env.production:"
grep "VITE_APP_STORE_SECURE_KEY" apps/web-ele/.env.production 2>/dev/null || echo "not found"

echo ""
echo "web-naive .env.production:"
grep "VITE_APP_STORE_SECURE_KEY" apps/web-naive/.env.production 2>/dev/null || echo "not found"

echo ""
echo "=== Check all .env files for web-tdesign ==="
for env_file in apps/web-tdesign/.env*; do
  echo "File: $env_file"
  cat "$env_file"
  echo ""
done

Length of output: 1437


Address the placeholder encryption key before production deployment.

The review comment is verified as accurate. The placeholder VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key in apps/web-tdesign/.env will be used for AES encryption of localStorage data (configured in packages/stores/src/setup.ts:26) unless explicitly overridden. Since .env.production contains no override for this key and no build-time validation exists, production builds will be compiled with the placeholder unless you:

  1. Create .env.local with a strong encryption key (development only; not suitable for production builds)
  2. Set VITE_APP_STORE_SECURE_KEY as an environment variable before running pnpm vite build --mode production
  3. Manually update .env.production with a generated encryption key

Without one of these steps, encrypted store data in production remains vulnerable.

🤖 Prompt for AI Agents
In apps/web-tdesign/.env around line 8, the VITE_APP_STORE_SECURE_KEY is a
placeholder ("please-replace-me-with-your-own-key") which will be baked into
builds if not overridden; replace it with a strong secret and do not commit it:
either (1) add a local-only .env.local with a securely generated key for
development, (2) set VITE_APP_STORE_SECURE_KEY as an environment variable before
running pnpm vite build --mode production, or (3) write a generated strong key
into .env.production for CI builds; ensure the key is high-entropy, kept out of
source control, and available to the build environment.

@likui628
Copy link
Collaborator

likui628 commented Nov 6, 2025

@copilot fix coderabbitai review and review this PR

Copy link
Contributor

Copilot AI commented Nov 6, 2025

@likui628 I've opened a new pull request, #6880, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 2 commits November 6, 2025 14:35
#6880)

* Initial plan

* fix: replace ant-design-vue with tdesign components

Co-authored-by: likui628 <[email protected]>

* fix: remove trailing comma in package.json

Co-authored-by: likui628 <[email protected]>

---------

Co-authored-by: copilot-swe-agent[bot] <[email protected]>
Co-authored-by: likui628 <[email protected]>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
apps/web-tdesign/src/store/auth.ts (1)

33-47: Critical: const reassignment will break the build.

Line 33 declares userInfo as const, but line 47 attempts to reassign it. This violates JavaScript const semantics and will cause a compilation error.

Apply this diff to fix the issue:

-    const userInfo: null | UserInfo = null;
+    let userInfo: null | UserInfo = null;
     try {
       loginLoading.value = true;
       const { accessToken } = await loginApi(params);
🧹 Nitpick comments (3)
apps/web-tdesign/src/adapter/vxe-table.ts (3)

27-31: Clarify the redundant response mapping.

Both result and list are mapped to 'items' in the proxy response configuration. This may be intentional to support different API response shapes, but please confirm this is the desired behavior.


42-47: Add defensive checks for image source.

The row[column.field] value is passed directly to the Image component without validation. Consider adding checks to handle cases where the field is missing or the value is not a valid image source.

Apply this diff to add a fallback:

     vxeUI.renderer.add('CellImage', {
       renderTableDefault(_renderOpts, params) {
         const { column, row } = params;
-        return h(Image, { src: row[column.field] });
+        const src = row[column.field];
+        return src ? h(Image, { src }) : null;
       },
     });

50-59: Consider handling missing text in CellLink renderer.

The button will render even when props?.text is undefined, resulting in an empty button. Consider returning null when no text is provided.

Apply this diff:

     vxeUI.renderer.add('CellLink', {
       renderTableDefault(renderOpts) {
         const { props } = renderOpts;
+        if (!props?.text) return null;
         return h(
           Button,
           { size: 'small', theme: 'primary', variant: 'text' },
           { default: () => props?.text },
         );
       },
     });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 33b7a60 and b472fbb.

📒 Files selected for processing (9)
  • apps/web-tdesign/package.json (1 hunks)
  • apps/web-tdesign/src/adapter/component/index.ts (1 hunks)
  • apps/web-tdesign/src/adapter/tdesign.ts (1 hunks)
  • apps/web-tdesign/src/adapter/vxe-table.ts (1 hunks)
  • apps/web-tdesign/src/api/request.ts (1 hunks)
  • apps/web-tdesign/src/locales/index.ts (1 hunks)
  • apps/web-tdesign/src/router/access.ts (1 hunks)
  • apps/web-tdesign/src/store/auth.ts (1 hunks)
  • apps/web-tdesign/src/views/demos/antd/index.vue (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/web-tdesign/package.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web-tdesign/src/locales/index.ts
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2024-12-04T04:43:22.179Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5013
File: docs/src/components/layout-ui/page.md:23-24
Timestamp: 2024-12-04T04:43:22.179Z
Learning: 在 `docs/src/components/layout-ui/page.md` 的 `Page` 组件中,`title` 和 `description` 属性有意使用 `string|slot` 类型表示法,表示它们可以接受字符串或插槽。

Applied to files:

  • apps/web-tdesign/src/views/demos/antd/index.vue
📚 Learning: 2024-12-04T04:41:30.161Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5013
File: docs/src/components/layout-ui/page.md:31-31
Timestamp: 2024-12-04T04:41:30.161Z
Learning: 在 Vben Admin 项目的 `Page` 组件中,`extra` 内容仅通过 slots 提供,没有对应的 prop 属性。

Applied to files:

  • apps/web-tdesign/src/views/demos/antd/index.vue
📚 Learning: 2025-01-19T09:24:38.942Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5436
File: apps/web-naive/src/api/request.ts:22-22
Timestamp: 2025-01-19T09:24:38.942Z
Learning: In the `createRequestClient` function signature of vue-vben-admin, the `baseURL` parameter is intentionally kept as the first parameter (before `options`) to maintain backward compatibility with existing code.

Applied to files:

  • apps/web-tdesign/src/api/request.ts
📚 Learning: 2024-11-05T10:34:13.846Z
Learnt from: ArthurDarkstone
Repo: vbenjs/vue-vben-admin PR: 4807
File: docs/src/components/common-ui/vben-vxe-table.md:65-84
Timestamp: 2024-11-05T10:34:13.846Z
Learning: In `docs/src/components/common-ui/vben-vxe-table.md`, the code examples are provided within markdown scripts for documentation and do not require import statements or explicit type annotations.

Applied to files:

  • apps/web-tdesign/src/adapter/vxe-table.ts
📚 Learning: 2024-11-05T10:38:55.166Z
Learnt from: ArthurDarkstone
Repo: vbenjs/vue-vben-admin PR: 4807
File: docs/src/_env/adapter/vxe-table.ts:0-0
Timestamp: 2024-11-05T10:38:55.166Z
Learning: In the documentation demos, such as in `docs/src/_env/adapter/vxe-table.ts`, it's acceptable to have less strict type safety and minimal error handling in custom renderers.

Applied to files:

  • apps/web-tdesign/src/adapter/vxe-table.ts
🧬 Code graph analysis (4)
apps/web-tdesign/src/router/access.ts (6)
packages/@core/base/typings/src/vue-router.d.ts (2)
  • GenerateMenuAndRoutesOptions (149-149)
  • ComponentRecordType (148-148)
packages/effects/access/src/accessible.ts (1)
  • generateAccessible (156-156)
apps/web-tdesign/src/adapter/tdesign.ts (1)
  • message (7-7)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (79-79)
apps/web-tdesign/src/api/core/menu.ts (1)
  • getAllMenusApi (8-10)
apps/web-naive/src/router/access.ts (1)
  • generateAccess (16-38)
apps/web-tdesign/src/api/request.ts (6)
packages/effects/hooks/src/use-app-config.ts (1)
  • useAppConfig (9-36)
packages/stores/src/modules/access.ts (1)
  • useAccessStore (51-123)
apps/web-tdesign/src/store/auth.ts (1)
  • useAuthStore (16-117)
apps/web-tdesign/src/api/core/auth.ts (1)
  • refreshTokenApi (31-35)
packages/effects/request/src/request-client/preset-interceptors.ts (3)
  • defaultResponseInterceptor (9-45)
  • authenticateResponseInterceptor (47-110)
  • errorMessageResponseInterceptor (112-165)
apps/web-tdesign/src/adapter/tdesign.ts (1)
  • message (7-7)
apps/web-tdesign/src/adapter/component/index.ts (3)
packages/@core/base/typings/src/helper.d.ts (1)
  • Recordable (130-130)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (79-79)
apps/web-tdesign/src/adapter/tdesign.ts (1)
  • notification (8-8)
apps/web-tdesign/src/store/auth.ts (9)
packages/stores/src/modules/access.ts (1)
  • useAccessStore (51-123)
packages/stores/src/modules/user.ts (1)
  • useUserStore (41-58)
apps/backend-mock/utils/mock-data.ts (1)
  • UserInfo (1-8)
apps/web-tdesign/src/api/core/auth.ts (3)
  • loginApi (24-26)
  • getAccessCodesApi (49-51)
  • logoutApi (40-44)
apps/web-tdesign/src/adapter/tdesign.ts (1)
  • notification (8-8)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (79-79)
packages/stores/src/setup.ts (1)
  • resetAllStores (51-60)
packages/constants/src/core.ts (1)
  • LOGIN_PATH (4-4)
apps/web-tdesign/src/api/core/user.ts (1)
  • getUserInfoApi (8-10)
🪛 Biome (2.1.2)
apps/web-tdesign/src/store/auth.ts

[error] 50-50: Can't assign userInfo because it's a constant.

This is where the variable is defined as constant.

Unsafe fix: Replace const with let if you assign it to a new value.

(lint/correctness/noConstAssign)

🔇 Additional comments (5)
apps/web-tdesign/src/adapter/vxe-table.ts (2)

1-9: LGTM!

The imports are well-organized and all appear necessary for the adapter configuration.


67-69: LGTM!

The exports cleanly expose the grid hook and re-export types from the plugin package, providing the necessary public API surface.

apps/web-tdesign/src/adapter/tdesign.ts (1)

1-9: LGTM! Clean adapter pattern.

The file provides a centralized re-export of TDesign Vue plugins, making them easily accessible throughout the application. This approach maintains consistency and simplifies imports.

apps/web-tdesign/src/api/request.ts (1)

96-103: No changes needed—MessagePlugin.error API supports string parameters.

The MessagePlugin.error signature accepts message: string | MessageOptions, so the current implementation calling message.error(errorMessage || msg) with string values is correct and requires no modification.

apps/web-tdesign/src/router/access.ts (1)

28-31: API signature verified as correct.

The object-based API pattern MessagePlugin.loading({...}) is the documented and supported approach for tdesign-vue-next, and [email protected] has no breaking changes affecting the MessagePlugin API. The code correctly uses message.loading({ content, duration }) as intended.

Comment on lines +1 to +67
<script lang="ts" setup>
import { Page } from '@vben/common-ui';

import { Button, Card, Space } from 'tdesign-vue-next';

import { message, notification } from '#/adapter/tdesign';

type NotificationType = 'error' | 'info' | 'success' | 'warning';

function info() {
message.info('How many roads must a man walk down');
}

function error() {
message.error({
content: 'Once upon a time you dressed so fine',
duration: 2500,
});
}

function warning() {
message.warning('How many roads must a man walk down');
}
function success() {
message.success('Cause you walked hand in hand With another man in my place');
}

function notify(type: NotificationType) {
notification[type]({
duration: 2500,
title: '说点啥呢',
});
}
</script>

<template>
<Page
description="支持多语言,主题功能集成切换等"
title="TDesign Vue组件使用演示"
>
<Card class="mb-5" title="按钮">
<Space>
<Button>Default</Button>
<Button theme="primary"> Primary </Button>
<Button theme="default"> Info </Button>
<Button theme="danger"> Error </Button>
</Space>
</Card>
<Card class="mb-5" title="Message">
<Space>
<Button @click="info"> 信息 </Button>
<Button theme="danger" @click="error"> 错误 </Button>
<Button @click="warning"> 警告 </Button>
<Button @click="success"> 成功 </Button>
</Space>
</Card>

<Card class="mb-5" title="Notification">
<Space>
<Button @click="notify('info')"> 信息 </Button>
<Button theme="danger" @click="notify('error')"> 错误 </Button>
<Button @click="notify('warning')"> 警告 </Button>
<Button @click="notify('success')"> 成功 </Button>
</Space>
</Card>
</Page>
</template>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Misleading filename: "antd" path for TDesign demo.

The file path includes demos/antd/ but the component demonstrates TDesign Vue components, not Ant Design. Consider renaming the directory to demos/tdesign/ for clarity.

Apply this change to align the path with the content:

  • Rename directory from apps/web-tdesign/src/views/demos/antd/ to apps/web-tdesign/src/views/demos/tdesign/
🤖 Prompt for AI Agents
In apps/web-tdesign/src/views/demos/antd/index.vue (lines 1-67) the directory
name "antd" is misleading because this file demonstrates TDesign Vue components;
rename the folder from apps/web-tdesign/src/views/demos/antd/ to
apps/web-tdesign/src/views/demos/tdesign/ and move this index.vue there, then
update all references to the old path across the repo (route definitions,
imports, storybook/demo registries, tests, and any packaging/config files) to
the new demos/tdesign path so nothing breaks.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
apps/web-tdesign/src/store/auth.ts (1)

99-104: Consider simplifying the variable declaration.

The initialization of userInfo to null on line 100 is immediately overwritten on line 101. You can simplify this to:

-  async function fetchUserInfo() {
-    let userInfo: null | UserInfo = null;
-    userInfo = await getUserInfoApi();
+  async function fetchUserInfo() {
+    const userInfo = await getUserInfoApi();
     userStore.setUserInfo(userInfo);
     return userInfo;
   }
apps/web-tdesign/src/views/demos/tdesign/index.vue (1)

41-48: Consider aligning button theme with semantic label.

Line 45 labels a button as "Info" but uses theme="default". This creates a semantic mismatch between the label and visual styling.

If demonstrating semantic button variants, consider either:

  • Changing the label to match the theme: <Button theme="default"> Default </Button>
  • Or removing this redundant button since line 43 already demonstrates the default theme
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b472fbb and 57620dc.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • apps/web-tdesign/src/adapter/component/index.ts (1 hunks)
  • apps/web-tdesign/src/router/routes/modules/demos.ts (1 hunks)
  • apps/web-tdesign/src/store/auth.ts (1 hunks)
  • apps/web-tdesign/src/views/demos/tdesign/index.vue (1 hunks)
  • vben-admin.code-workspace (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web-tdesign/src/router/routes/modules/demos.ts
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2024-12-04T04:43:22.179Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5013
File: docs/src/components/layout-ui/page.md:23-24
Timestamp: 2024-12-04T04:43:22.179Z
Learning: 在 `docs/src/components/layout-ui/page.md` 的 `Page` 组件中,`title` 和 `description` 属性有意使用 `string|slot` 类型表示法,表示它们可以接受字符串或插槽。

Applied to files:

  • apps/web-tdesign/src/views/demos/tdesign/index.vue
📚 Learning: 2024-12-04T04:41:30.161Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5013
File: docs/src/components/layout-ui/page.md:31-31
Timestamp: 2024-12-04T04:41:30.161Z
Learning: 在 Vben Admin 项目的 `Page` 组件中,`extra` 内容仅通过 slots 提供,没有对应的 prop 属性。

Applied to files:

  • apps/web-tdesign/src/views/demos/tdesign/index.vue
🧬 Code graph analysis (2)
apps/web-tdesign/src/store/auth.ts (9)
packages/stores/src/modules/access.ts (1)
  • useAccessStore (51-123)
packages/stores/src/modules/user.ts (1)
  • useUserStore (41-58)
apps/backend-mock/utils/mock-data.ts (1)
  • UserInfo (1-8)
apps/web-tdesign/src/api/core/auth.ts (3)
  • loginApi (24-26)
  • getAccessCodesApi (49-51)
  • logoutApi (40-44)
apps/web-tdesign/src/adapter/tdesign.ts (1)
  • notification (8-8)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (79-79)
packages/stores/src/setup.ts (1)
  • resetAllStores (51-60)
packages/constants/src/core.ts (1)
  • LOGIN_PATH (4-4)
apps/web-tdesign/src/api/core/user.ts (1)
  • getUserInfoApi (8-10)
apps/web-tdesign/src/adapter/component/index.ts (3)
packages/@core/base/typings/src/helper.d.ts (1)
  • Recordable (130-130)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (79-79)
apps/web-tdesign/src/adapter/tdesign.ts (1)
  • notification (8-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: Check (ubuntu-latest)
  • GitHub Check: Check (windows-latest)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: post-update (windows-latest)
🔇 Additional comments (13)
vben-admin.code-workspace (1)

19-22: LGTM!

The new workspace folder entry for the TDesign app follows the established naming convention and is correctly positioned in alphabetical order among the web applications.

apps/web-tdesign/src/store/auth.ts (5)

1-14: LGTM: Imports are well-organized.

All necessary dependencies are imported and used appropriately throughout the file.


16-22: LGTM: Store initialization follows Pinia best practices.

The composition API setup with proper dependency injection is correct.


79-97: LGTM: Logout flow is correct.

The function properly handles the logout process with appropriate error suppression and cleanup.


106-116: LGTM: Store API surface is complete.

The $reset function and return statement correctly expose the store's public API.


28-77: Based on my web search, I was unable to find definitive documentation for TDesign's NotificationPlugin duration parameter unit. While generic Vue 3 notification libraries typically use milliseconds for the duration parameter, and Ant Design uses seconds with a default of 4.5 seconds, TDesign's specific implementation remains unconfirmed from publicly available sources.

Verify TDesign notification duration unit

The code uses duration: 3000 in the notification call (line 66). While this appears to follow the millisecond convention used by most Vue notification libraries (equivalent to 3 seconds display time), the exact unit specification for TDesign should be confirmed against your project's TDesign documentation or by inspecting the TDesign component source in your node_modules.

apps/web-tdesign/src/views/demos/tdesign/index.vue (3)

1-67: Previous path concern appears resolved.

The earlier review comment about the misleading "antd" directory name has been addressed—the file is now correctly located at demos/tdesign/.


28-67: Inconsistent localization approach.

The component mixes Chinese UI text (template labels, titles, notification titles) with English message content (lines 11, 16, 22, 25) without using the i18n system. Line 38's description claims "支持多语言" (supports multiple languages), but all text is hardcoded.

Consider using $t() for all user-facing strings to demonstrate proper i18n integration.

⛔ Skipped due to learnings
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5587
File: playground/src/views/examples/loading/index.vue:15-18
Timestamp: 2025-02-23T04:21:24.691Z
Learning: Chinese text in the description of the loading component example (`playground/src/views/examples/loading/index.vue`) is intentionally kept without i18n support.
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5013
File: docs/src/components/layout-ui/page.md:23-24
Timestamp: 2024-12-04T04:43:22.179Z
Learning: 在 `docs/src/components/layout-ui/page.md` 的 `Page` 组件中,`title` 和 `description` 属性有意使用 `string|slot` 类型表示法,表示它们可以接受字符串或插槽。
Learnt from: ArthurDarkstone
Repo: vbenjs/vue-vben-admin PR: 4807
File: docs/src/demos/vben-vxe-table/custom-cell/index.vue:104-106
Timestamp: 2024-11-05T10:34:03.759Z
Learning: Cannot use i18n (internationalization) in the docs components in the `docs/` directory.

8-8: Verify if TDesign's NotificationPlugin method types make the local NotificationType definition redundant.

The adapter exports NotificationPlugin directly from tdesign-vue-next. Since NotificationPlugin should have built-in method typings (.error(), .info(), .success(), .warning()), the local NotificationType union may be unnecessary. However, without inspecting TDesign's actual type definitions, this cannot be confirmed. The code works correctly as-is. Consider checking TDesign's type definitions to see if removing this local type and relying on method signature inference would be viable.

apps/web-tdesign/src/adapter/component/index.ts (4)

11-11: Previous issue resolved: TDesign notification now used.

The import now correctly uses the TDesign notification from the adapter instead of Ant Design Vue.


181-193: Previous issue resolved: PrimaryButton now uses correct theme.

The PrimaryButton now correctly uses theme: 'primary' (line 190), fixing the previous issue where it was identical to DefaultButton. The ghost variant handling logic (lines 182-187) also looks correct, properly converting variant='ghost' to TDesign's ghost prop with variant='base'.


196-201: Good defensive programming for RangePicker.

The RangePicker wrapper correctly ensures modelValue is always an array using the nullish coalescing operator (?? []). This prevents potential runtime errors when the picker expects an array for date ranges.


217-226: Notification implementation looks correct.

The copyPreferencesSuccess message correctly uses TDesign's notification API with proper property names (title, content, placement: 'bottom-right'). This aligns with TDesign Vue Next's notification component API.

Comment on lines +134 to +146
ApiSelect: withDefaultPlaceholder(
{
...ApiComponent,
name: 'ApiSelect',
},
'select',
{
component: Select,
loadingSlot: 'suffixIcon',
visibleEvent: 'onDropdownVisibleChange',
modelPropName: 'value',
},
),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify TDesign Select API compatibility.

The ApiSelect configuration specifies visibleEvent: 'onDropdownVisibleChange' and loadingSlot: 'suffixIcon'. Ensure these match TDesign Select's actual API. TDesign components may use different event/slot naming conventions than Ant Design (e.g., onVisibleChange instead of onDropdownVisibleChange, or suffixIcon might need to be a prop rather than a slot).


🏁 Script executed:

#!/bin/bash
# Search for TDesign Select usage patterns and event handlers in the codebase
rg -n 'onDropdownVisibleChange|onVisibleChange' --type=ts --type=vue -C2

# Search for suffixIcon usage with TDesign Select
rg -n 'suffixIcon' --type=ts --type=vue -C2

Length of output: 55



Actually, I need to check the codebase. Let me refine:



🏁 Script executed:

#!/bin/bash
# Search for event handlers without type flag (works for .ts files)
rg -n 'onDropdownVisibleChange|onVisibleChange' --type=ts -C2

# Search for suffixIcon in TypeScript files
rg -n 'suffixIcon' --type=ts -C2

# Search in Vue files using glob pattern
rg -n 'onDropdownVisibleChange|onVisibleChange' -g "*.vue" -C2

# Search for suffixIcon in Vue files
rg -n 'suffixIcon' -g "*.vue" -C2

# Search for tdesign Select imports and configurations
rg -n 'from.*tdesign.*Select|import.*Select' --type=ts -C2

Length of output: 8090


🏁 Script executed:

#!/bin/bash
# Search for tdesign Select imports and component definitions
rg -n 'from.*tdesign|import.*Select' --type=ts -C3

# Look for ApiSelect or component adapter configurations
rg -n 'ApiSelect|visibleEvent|loadingSlot' --type=ts -C2

# Check TDesign Select event names in codebase usage
rg -n 'Select.*event|onVisible|onDropdown' -g "*.vue" -C2

Length of output: 15061



---

🌐 Web query:

```web
TDesign Vue Select component onVisibleChange event API

💡 Result:

Short answer — Select's visibility callback receives (visible, context).

API: onVisibleChange(visible: boolean, context: PopupVisibleChangeContext)

  • visible: whether the popup is shown (true/false). [1]
  • context: object with fields like trigger (source: 'trigger' | 'document' | etc.) and optional e (original event). Use context.trigger to know why it changed. Example usage: (visible, ctx) => { if (ctx.trigger === 'document') ... }. [1][2]

Sources:
[1] tdesign popup typings (PopupVisibleChangeContext / emit signature).
[2] Example using (visible, PopupVisibleChangeContext) in a tdesign-based blog.



---

🌐 Web query:

```web
TDesign Vue Select component suffixIcon slot

💡 Result:

Short answer: TDesign Vue Select supports a suffixIcon slot named "suffixIcon" (and also a "suffix" slot for custom content). Use it like:

Example:

<template #suffixIcon>

<template #suffix>
<button @click="clear">Clear

References: TDesign changelog noting Select added suffix/suffixIcon and slot fixes [1]; TDesign Vue repo/docs overview [2].

Sources:
[1] changelog / package notes for tdesign-vue-next (mentions Select suffix/suffixIcon).
[2] Tencent tdesign-vue GitHub repository.


Fix incorrect TDesign Select event name at line 143.

The ApiSelect configuration uses visibleEvent: 'onDropdownVisibleChange', which is Ant Design's event name. TDesign Select uses onVisibleChange. This mismatch will break dropdown visibility tracking. Change line 143 to visibleEvent: 'onVisibleChange' to match TDesign's API (and align with ApiTreeSelect on line 159, which correctly uses the same event).

    ApiSelect: withDefaultPlaceholder(
      {
        ...ApiComponent,
        name: 'ApiSelect',
      },
      'select',
      {
        component: Select,
        loadingSlot: 'suffixIcon',
        visibleEvent: 'onVisibleChange',
        modelPropName: 'value',
      },
    ),
🤖 Prompt for AI Agents
In apps/web-tdesign/src/adapter/component/index.ts around lines 134 to 146, the
ApiSelect config uses the Ant Design event name 'onDropdownVisibleChange' which
doesn't match TDesign's API and breaks visibility tracking; change the
visibleEvent value to 'onVisibleChange' (same as ApiTreeSelect) so dropdown
visibility hooks bind correctly.

Comment on lines +171 to +175
IconPicker: withDefaultPlaceholder(IconPicker, 'select', {
iconSlot: 'addonAfter',
inputComponent: Input,
modelValueProp: 'value',
}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify TDesign Input slot compatibility for IconPicker.

The IconPicker configuration uses iconSlot: 'addonAfter' with TDesign's Input component. TDesign Input may not support an addonAfter slot (this is an Ant Design concept). TDesign typically uses suffix or suffixIcon props/slots instead. Verify this configuration matches TDesign Input's API to avoid runtime rendering issues.


🏁 Script executed:

#!/bin/bash
# Search for TDesign Input slot usage patterns in the codebase
rg -n 'addonAfter|suffix|suffixIcon' --type=ts --type=vue -C3 -g '**/tdesign**' -g '**Input**'

# Also check IconPicker usage across the codebase
rg -n 'IconPicker' --type=ts --type=vue -C3

Length of output: 55



Actually, let me revise - I need access to the repo files:

---

🏁 Script executed:

```shell
#!/bin/bash
# Search for IconPicker and Input slot patterns without type restrictions
rg -n 'IconPicker' -C5

# Search for addonAfter, suffix, or suffixIcon usage patterns
rg -n 'addonAfter|suffix|suffixIcon' -C3 apps/web-tdesign/src/

# Look for TDesign Input component definition or slot documentation
find . -name "*.d.ts" -o -name "*.ts" -o -name "*.vue" 2>/dev/null | xargs grep -l "TdInput\|Input.*slot" | head -10

Length of output: 23848


🏁 Script executed:

#!/bin/bash
# Search for IconPicker configuration usage
rg -n 'IconPicker' -C5

# Search for slot patterns in the tdesign adapter directory
rg -n 'addonAfter|suffix|suffixIcon' apps/web-tdesign/src/

# Search for Input component usage with slots in the adapter
rg -n 'Input.*:' apps/web-tdesign/src/adapter/ -C3

Length of output: 23140




🌐 Web query:

TDesign Vue Input component slots API suffix prefix

💡 Result:

TDesign Vue Input supports front/back adornments via prepend/append props (and an InputAdornment subcomponent) and also standard prefix/suffix slots (named slots). Use the named slots: prefix, suffix (inside the input), and prepend, append (outside as input-group). See the component props/types for prepend/append and the input-adornment types. [1][2][3]

Example (vue template):


<template #prefix>🔍
<template #suffix>@
<template #prepend>http://
<template #append>.com

Sources: tdesign input-adornment props/types and input-adornment declaration. [1][2]; example slot names documented in input component guides. [3]


Change TDesign Input slot from addonAfter to suffix.

TDesign Vue Input supports named slots: prefix and suffix (inside the input), and prepend and append (outside as input-group). The configuration uses iconSlot: 'addonAfter' which is an Ant Design API and will not work with TDesign Input. This will cause the icon picker slot to fail at runtime.

Change line 172 from:

      iconSlot: 'addonAfter',

to:

      iconSlot: 'suffix',

(Align with web-naive's suffix pattern for TDesign-compatible configuration.)

🤖 Prompt for AI Agents
In apps/web-tdesign/src/adapter/component/index.ts around lines 171 to 175, the
IconPicker configuration uses the Ant Design slot name 'addonAfter' which
TDesign Input does not support; replace iconSlot: 'addonAfter' with iconSlot:
'suffix' so the icon renders inside the TDesign Input as expected and aligns
with the web-naive suffix pattern.

Comment on lines +10 to +23
function info() {
message.info('How many roads must a man walk down');
}
function error() {
message.error({
content: 'Once upon a time you dressed so fine',
duration: 2500,
});
}
function warning() {
message.warning('How many roads must a man walk down');
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Duplicate message content in info and warning functions.

Both info() and warning() display the same message: "How many roads must a man walk down". This appears to be a copy-paste oversight.

Consider using distinct messages for each type:

 function warning() {
-  message.warning('How many roads must a man walk down');
+  message.warning('This is a warning message');
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function info() {
message.info('How many roads must a man walk down');
}
function error() {
message.error({
content: 'Once upon a time you dressed so fine',
duration: 2500,
});
}
function warning() {
message.warning('How many roads must a man walk down');
}
function info() {
message.info('How many roads must a man walk down');
}
function error() {
message.error({
content: 'Once upon a time you dressed so fine',
duration: 2500,
});
}
function warning() {
message.warning('This is a warning message');
}
🤖 Prompt for AI Agents
In apps/web-tdesign/src/views/demos/tdesign/index.vue around lines 10 to 23, the
info() and warning() functions both display the identical message "How many
roads must a man walk down" (likely a copy/paste mistake); update one of the
functions to use a distinct, appropriate message for its level (e.g., change
info() or warning() to a different string that reflects its intent) so each
message type shows unique content.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
package.json (1)

34-36: Script is out of alphabetical order.

The build:tdesign script should be positioned after build:play to maintain alphabetical ordering consistency with the existing build scripts. Currently, build scripts are ordered: build:antd, build:docs, build:ele, build:naive, then build:tdesign, then build:play — but tdesign should come after play.

Move the build:tdesign script after build:play to maintain alphabetical consistency:

     "build:naive": "pnpm run build --filter=@vben/web-naive",
-    "build:tdesign": "pnpm run build --filter=@vben/web-tdesign",
     "build:play": "pnpm run build --filter=@vben/playground",
+    "build:tdesign": "pnpm run build --filter=@vben/web-tdesign",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57620dc and bd8ff73.

📒 Files selected for processing (6)
  • apps/web-tdesign/src/adapter/tdesign.ts (1 hunks)
  • docs/src/en/guide/essentials/development.md (1 hunks)
  • docs/src/en/guide/introduction/thin.md (1 hunks)
  • docs/src/guide/essentials/development.md (1 hunks)
  • docs/src/guide/introduction/thin.md (1 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-02-08T07:36:14.722Z
Learnt from: dingdayu
Repo: vbenjs/vue-vben-admin PR: 5500
File: packages/@core/ui-kit/tabs-ui/src/components/tabs-chrome/tabs.vue:51-51
Timestamp: 2025-02-08T07:36:14.722Z
Learning: The project uses changesets for version management and changelog generation. Breaking changes should be documented by creating a new changeset using `pnpm changeset` command, selecting affected packages, choosing "major" as the bump type, and providing a detailed description of the change and its impact.

Applied to files:

  • docs/src/guide/essentials/development.md
  • docs/src/en/guide/introduction/thin.md
  • docs/src/en/guide/essentials/development.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test (windows-latest)
  • GitHub Check: Check (ubuntu-latest)
  • GitHub Check: Check (windows-latest)
  • GitHub Check: post-update (windows-latest)
  • GitHub Check: post-update (ubuntu-latest)
🔇 Additional comments (5)
apps/web-tdesign/src/adapter/tdesign.ts (1)

1-5: LGTM! Clean adapter pattern.

The re-export structure is clean and follows best practices. The naming simplification (removing the Plugin suffix and using lowercase) provides a more intuitive API surface for consumers of this adapter.

docs/src/guide/introduction/thin.md (1)

63-63: Documentation example is consistent with root package.json.

The script addition in the documentation example matches the root package.json structure. Once the root file ordering is corrected, this documentation should be updated to match for consistency.

docs/src/guide/essentials/development.md (1)

63-64: LGTM! Documentation example is well-commented and consistent.

The script addition includes a clear Chinese comment explaining its purpose, matching the documentation style of other build scripts.

docs/src/en/guide/introduction/thin.md (1)

59-59: English documentation example is consistent with Chinese version.

The English translation maintains the same structure and script addition as the Chinese version.

docs/src/en/guide/essentials/development.md (1)

63-64: LGTM! English documentation example is well-translated and consistent.

The script addition includes a clear English explanation matching the style of other build scripts.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
apps/web-ele/src/router/routes/modules/vben.ts (1)

69-78: Add icon for menu consistency

Other Vben preview entries set an icon so the menu shows the product logo. Without one, this new item renders without a graphic. Please add the TDesign icon just like the other previews.

       {
         name: 'VbenTDesign',
         path: '/vben-admin/tdesign',
         component: IFrameView,
         meta: {
           badgeType: 'dot',
+          icon: 'logos:tdesign',
           link: VBEN_TD_PREVIEW_URL,
           title: $t('demos.vben.tdesign'),
         },
       },
apps/web-naive/src/router/routes/modules/vben.ts (1)

58-67: Include the TDesign icon in meta

Sibling routes specify an icon so their menu entries display correctly. This new TDesign item omits one, leaving an empty slot. Please add the TDesign logo to keep the menu uniform.

       {
         name: 'VbenTDesign',
         path: '/vben-admin/tdesign',
         component: IFrameView,
         meta: {
           badgeType: 'dot',
+          icon: 'logos:tdesign',
           link: VBEN_TD_PREVIEW_URL,
           title: $t('demos.vben.tdesign'),
         },
       },
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dc77721 and be84330.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • apps/web-antd/src/locales/langs/en-US/demos.json (1 hunks)
  • apps/web-antd/src/locales/langs/zh-CN/demos.json (1 hunks)
  • apps/web-antd/src/router/routes/modules/vben.ts (2 hunks)
  • apps/web-ele/src/locales/langs/en-US/demos.json (1 hunks)
  • apps/web-ele/src/locales/langs/zh-CN/demos.json (1 hunks)
  • apps/web-ele/src/router/routes/modules/vben.ts (2 hunks)
  • apps/web-naive/src/locales/langs/en-US/demos.json (1 hunks)
  • apps/web-naive/src/locales/langs/zh-CN/demos.json (1 hunks)
  • apps/web-naive/src/router/routes/modules/vben.ts (2 hunks)
  • apps/web-tdesign/.env.development (1 hunks)
  • apps/web-tdesign/src/router/routes/modules/vben.ts (1 hunks)
  • packages/@core/base/shared/src/constants/vben.ts (1 hunks)
  • playground/src/locales/langs/en-US/demos.json (1 hunks)
  • playground/src/locales/langs/zh-CN/demos.json (1 hunks)
  • playground/src/router/routes/modules/vben.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-02-08T07:05:28.825Z
Learnt from: dingdayu
Repo: vbenjs/vue-vben-admin PR: 5500
File: packages/stores/src/modules/tabbar.ts:557-559
Timestamp: 2025-02-08T07:05:28.825Z
Learning: In Vue Vben Admin, while tab identification uses `path` to group tabs with same path but different queries, router navigation operations (router.push) and new window operations should use `fullPath` to preserve the complete URL including query parameters. This applies specifically to:
1. Router navigation in tab maximize/restore feature
2. Opening tabs in new window via openTabInNewWindow

Applied to files:

  • apps/web-naive/src/router/routes/modules/vben.ts
  • apps/web-antd/src/router/routes/modules/vben.ts
📚 Learning: 2024-12-04T04:41:30.161Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5013
File: docs/src/components/layout-ui/page.md:31-31
Timestamp: 2024-12-04T04:41:30.161Z
Learning: 在 Vben Admin 项目的 `Page` 组件中,`extra` 内容仅通过 slots 提供,没有对应的 prop 属性。

Applied to files:

  • apps/web-naive/src/router/routes/modules/vben.ts
📚 Learning: 2025-02-23T04:21:24.691Z
Learnt from: mynetfan
Repo: vbenjs/vue-vben-admin PR: 5587
File: playground/src/views/examples/loading/index.vue:15-18
Timestamp: 2025-02-23T04:21:24.691Z
Learning: Chinese text in the description of the loading component example (`playground/src/views/examples/loading/index.vue`) is intentionally kept without i18n support.

Applied to files:

  • playground/src/locales/langs/zh-CN/demos.json
🧬 Code graph analysis (5)
apps/web-naive/src/router/routes/modules/vben.ts (2)
apps/web-naive/src/layouts/index.ts (1)
  • IFrameView (6-6)
packages/@core/base/shared/src/constants/vben.ts (1)
  • VBEN_TD_PREVIEW_URL (28-28)
playground/src/router/routes/modules/vben.ts (1)
packages/@core/base/shared/src/constants/vben.ts (1)
  • VBEN_TD_PREVIEW_URL (28-28)
apps/web-antd/src/router/routes/modules/vben.ts (1)
packages/@core/base/shared/src/constants/vben.ts (1)
  • VBEN_TD_PREVIEW_URL (28-28)
apps/web-ele/src/router/routes/modules/vben.ts (2)
apps/web-ele/src/layouts/index.ts (1)
  • IFrameView (6-6)
packages/@core/base/shared/src/constants/vben.ts (1)
  • VBEN_TD_PREVIEW_URL (28-28)
apps/web-tdesign/src/router/routes/modules/vben.ts (4)
packages/@core/base/shared/src/constants/vben.ts (6)
  • VBEN_LOGO_URL (14-15)
  • VBEN_DOC_URL (9-9)
  • VBEN_GITHUB_URL (4-4)
  • VBEN_NAIVE_PREVIEW_URL (24-24)
  • VBEN_ANT_PREVIEW_URL (26-26)
  • VBEN_ELE_PREVIEW_URL (22-22)
apps/web-tdesign/src/locales/index.ts (1)
  • $t (79-79)
apps/web-tdesign/src/layouts/index.ts (1)
  • IFrameView (6-6)
packages/icons/src/svg/index.ts (1)
  • SvgAntdvLogoIcon (21-21)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: post-update (ubuntu-latest)
  • GitHub Check: post-update (windows-latest)
🔇 Additional comments (9)
apps/web-tdesign/.env.development (1)

12-13: Verify intent: DevTools disabled in development environment.

VITE_DEVTOOLS=false is atypical for a development environment, where Vue DevTools are normally enabled to aid debugging and inspection. Please clarify whether this is intentional (e.g., performance optimization, security measure) or should be true.

apps/web-antd/src/locales/langs/zh-CN/demos.json (1)

10-11: LGTM! Clean locale addition.

The new TDesign translation entry is properly formatted and consistent with the existing pattern for other UI library versions.

apps/web-naive/src/locales/langs/zh-CN/demos.json (1)

12-13: LGTM! Consistent locale addition.

The TDesign translation entry follows the same pattern used in other apps and is properly formatted.

apps/web-naive/src/locales/langs/en-US/demos.json (1)

12-13: LGTM! Proper English locale entry.

The English translation for TDesign is consistent with the naming convention used for other UI library entries.

apps/web-ele/src/locales/langs/zh-CN/demos.json (1)

11-12: LGTM! Consistent Chinese locale entry.

The translation addition maintains consistency across all app variants.

apps/web-antd/src/router/routes/modules/vben.ts (1)

9-9: LGTM! Proper constant import.

The VBEN_TD_PREVIEW_URL import is correctly placed and aligns with the pattern used for other preview URLs.

playground/src/locales/langs/en-US/demos.json (1)

68-69: LGTM! Playground locale updated.

The TDesign entry is properly added to the playground environment, maintaining consistency with the app-level locale files.

apps/web-ele/src/locales/langs/en-US/demos.json (1)

11-12: LGTM! English locale completed.

The English translation properly complements the Chinese locale entry for the web-ele app.

apps/web-antd/src/locales/langs/en-US/demos.json (1)

10-11: LGTM! Complete locale coverage.

The English translation entry completes the TDesign locale support across all app variants. All locale changes in this PR are consistent and properly formatted.

@likui628
Copy link
Collaborator

likui628 commented Nov 6, 2025

@jinmao88 还差tdesign的部署
export const VBEN_TD_PREVIEW_URL = 'https://tdesign.vben.pro';

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants