-
Notifications
You must be signed in to change notification settings - Fork 8.2k
feat: add app with Tdesign #6836
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
WalkthroughIntroduces a new web application ( Changes
Sequence Diagram(s)sequenceDiagram
participant Browser
participant Bootstrap
participant AuthGuard
participant AuthAPI
participant Router
participant View
Browser->>Bootstrap: initApplication()
Bootstrap->>Bootstrap: initPreferences(namespace)
Bootstrap->>Bootstrap: import bootstrap module
Bootstrap->>Bootstrap: bootstrap(namespace)<br/>- setupI18n<br/>- createPinia<br/>- setupRouter
Router->>AuthGuard: setupAccessGuard(router)
AuthGuard->>AuthGuard: beforeEach hook
rect rgb(200, 220, 255)
Note over AuthGuard: First Navigation
AuthGuard->>AuthGuard: Check if auth required
alt Unauthenticated
AuthGuard->>Router: redirect to LOGIN_PATH
else Authenticated
AuthGuard->>AuthAPI: generateAccess(options)
AuthAPI->>AuthAPI: fetchMenuListAsync()
AuthAPI->>AuthAPI: getAllMenusApi()
AuthGuard->>AuthGuard: Cache access state<br/>(menus, routes, checked)
AuthGuard->>Router: resolve intended route
end
end
Router->>View: render matched route
View->>Browser: display page
sequenceDiagram
participant App
participant RequestInterceptor
participant API
participant ResponseInterceptor
participant Store as Auth Store
participant RefreshFlow
App->>App: authLogin(credentials)
App->>RequestInterceptor: POST /auth/login<br/>+ Authorization header
RequestInterceptor->>API: send request
API->>API: validate credentials
rect rgb(200, 220, 255)
Note over API: Success Path
API-->>ResponseInterceptor: 200 + accessToken
ResponseInterceptor->>Store: save accessToken
ResponseInterceptor->>API: fetch user info
ResponseInterceptor->>API: fetch access codes
ResponseInterceptor->>Store: save user/codes
ResponseInterceptor-->>App: login success
end
rect rgb(255, 220, 200)
Note over API: Token Expiry Path
API-->>ResponseInterceptor: 401 Unauthorized
ResponseInterceptor->>RefreshFlow: doRefreshToken()
RefreshFlow->>API: POST /auth/refresh<br/>+ withCredentials
API->>Store: save new accessToken
RefreshFlow-->>ResponseInterceptor: retry original request
ResponseInterceptor-->>App: request succeeds
end
sequenceDiagram
participant App
participant Adapter as ComponentAdapter
participant GlobalState
participant Template
App->>Adapter: initComponentAdapter()
rect rgb(200, 220, 255)
Note over Adapter: Register Components
Adapter->>Adapter: withDefaultPlaceholder<br/>(ApiSelect, ApiTreeSelect)
Adapter->>Adapter: wrap Button variants<br/>(Default, Primary)
Adapter->>Adapter: wrap FormComponents<br/>(Input, Select, etc.)
end
Adapter->>GlobalState: setComponents(components)
GlobalState->>GlobalState: store components map
Adapter->>Adapter: setupVbenForm<br/>with ComponentType
Adapter->>Adapter: define copyPreferencesSuccess<br/>message
Adapter-->>App: initComponentAdapter complete
App->>Template: render form
Template->>GlobalState: useComponentType()
GlobalState-->>Template: get registered components
Template->>Template: render with TD-Design UI
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes Rationale: This PR introduces a complete new application ( Possibly related PRs
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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-labelattribute, 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-motionmedia 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 withrequestAnimationFrameandquerySelector, which should be extracted to a shared utility function for better maintainability.See the comment on
lock-screen.vuelines 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
borderColorat 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
setDefaultModalPropsandsetDefaultDrawerPropsshould 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
InputPasswordandMentions, 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
⛔ Files ignored due to path filters (1)
apps/web-tdesign/public/favicon.icois 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:
- These changes align with the TD-Design visual specifications.
- Animation behavior has been tested against components that rely on
.side-content.- 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-lgtorounded-mdreduces 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-nextto^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
getFieldComponentRefto 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
getFieldComponentRefaligns with the auto-focus enhancement implemented in theonOpenedhook 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
handerOpenAutoFocustohandleOpenAutoFocusfixes a typo and aligns with standard naming conventions.
212-216: Verify the design rationale forrequestAnimationFrameinhandleOpenedand alignment withhandleClosed.The
handleOpenedfunction (lines 212–216) defers the callback usingrequestAnimationFrame, whilehandleClosed(lines 218–220) executes its callback immediately. This inconsistency is the only instance ofrequestAnimationFramein the popup-ui component.Verify:
- Is the deferred execution necessary for
onOpened(e.g., waiting for DOM paint/layout)?- Why
handleCloseddoes not require the same pattern?- Could rapid open/close cycles cause
onOpenedto 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
dataSideprop 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-contentis more semantic, and the:data-sidebinding 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%]tow-2/5creates symmetry with the left panel, anddata-side="right"correctly identifies the panel position.
89-96: Panel state flags are guaranteed mutually exclusive.The computed properties
authPanelLeft,authPanelRight, andauthPanelCenterderive 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-configpackage is properly declared in the rootpackage.jsonwith"workspace:*"protocol, and the./postcsssubpath export is correctly defined in itspackage.json. The source file exists atinternal/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:foldandep:expandare valid icons in the Element Plus/Iconify library. The codebase search confirms these icons are used only at the specified lines invben-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.antdreferences a local Ant Design demo component (#/views/demos/antd/index.vue), whiledemos.vben.naive-uianddemos.vben.element-pluslabel 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.tsimports itpackages/effects/layouts/src/widgets/preferences/blocks/input-item.vueimports itpackages/@core/ui-kit/shadcn-ui/src/components/input-password/input-password.vueimports itThe
muted-foregroundcolor 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
Fallbackcomponent with status500for internal server error scenarios.apps/web-tdesign/src/views/_core/authentication/qrcode-login.vue (1)
1-10: LGTM!The component correctly wraps the
AuthenticationQrCodeLogincomponent and properly binds theLOGIN_PATHconstant 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
splitHandleandsplitLineprovides 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-centerclasses 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-primaryclass 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.productionwithVITE_GLOB_API_URL=https://mock-napi.vben.pro/api.The project design allows developers to dynamically modify the API endpoint in
dist/_app.config.jsafter 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
applicationobject serves as a valid placeholder for future configuration.
9-15: Proxy configuration is correct and intentional.The double
/apipattern you questioned is the correct design. The mock server serves athttp://localhost:5320/api, and the proxy correctly rewrites requests to reach that endpoint. The request flow/api/users→/users→http://localhost:5320/api/usersis 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
generateAccessfunction 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
navTofunction 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
defaultResponseInterceptorwith appropriate field mappings- Token refresh logic via
authenticateResponseInterceptorwith 401 handlingapps/web-tdesign/src/adapter/component/index.ts (1)
128-210: LGTM! Component adapter initialization is well-structured.The
initComponentAdapterfunction properly:
- Registers TDesign components with appropriate placeholder handling
- Uses the
withDefaultPlaceholderHOC for consistent UX- Configures API components with correct prop mappings
- Registers components in global shared state
| @@ -0,0 +1,8 @@ | |||
| # 应用标题 | |||
| VITE_APP_TITLE=Vben Admin Antd | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct the application title to reflect Tdesign.
The title shows "Vben Admin Antd" but this PR adds a Tdesign-based application, not Ant Design. This creates a branding inconsistency.
Apply this diff:
-VITE_APP_TITLE=Vben Admin Antd
+VITE_APP_TITLE=Vben Admin Tdesign📝 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.
| VITE_APP_TITLE=Vben Admin Antd | |
| VITE_APP_TITLE=Vben Admin Tdesign |
🧰 Tools
🪛 dotenv-linter (4.0.0)
[warning] 2-2: [ValueWithoutQuotes] This value needs to be surrounded in quotes
(ValueWithoutQuotes)
🤖 Prompt for AI Agents
In apps/web-tdesign/.env around line 2, the VITE_APP_TITLE is incorrectly set to
"Vben Admin Antd"; update this environment variable to reflect the Tdesign
branding (for example "Vben Admin Tdesign" or "Vben Admin TDesign") so the app
title matches the Tdesign-based UI, save the .env file, and ensure any build/dev
caches are cleared so the new title is picked up.
| VITE_APP_TITLE=Vben Admin Antd | ||
|
|
||
| # 应用命名空间,用于缓存、store等功能的前缀,确保隔离 | ||
| VITE_APP_NAMESPACE=vben-web-antd |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update namespace to match the Tdesign app.
The namespace references "vben-web-antd" but should be "vben-web-tdesign" to properly identify this application and avoid potential cache/storage collisions.
Apply this diff:
-VITE_APP_NAMESPACE=vben-web-antd
+VITE_APP_NAMESPACE=vben-web-tdesign📝 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.
| VITE_APP_NAMESPACE=vben-web-antd | |
| VITE_APP_NAMESPACE=vben-web-tdesign |
🤖 Prompt for AI Agents
In apps/web-tdesign/.env around line 5, the VITE_APP_NAMESPACE is set to
"vben-web-antd" but should be "vben-web-tdesign"; update the value to
VITE_APP_NAMESPACE=vben-web-tdesign to match the Tdesign app and prevent
cache/storage collisions.
| VITE_APP_NAMESPACE=vben-web-antd | ||
|
|
||
| # 对store进行加密的密钥,在将store持久化到localStorage时会使用该密钥进行加密 | ||
| VITE_APP_STORE_SECURE_KEY=please-replace-me-with-your-own-key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Replace the placeholder secure key before deployment.
The placeholder value please-replace-me-with-your-own-key must be replaced with a proper cryptographic key. Deploying with this placeholder would compromise the security of encrypted store data.
Ensure this key is replaced with a strong, randomly generated value before any deployment or production use.
I'll verify this security concern by examining the repository structure and how this key is used.
🏁 Script executed:
#!/bin/bash
# Check if the .env file exists and view its contents
if [ -f "apps/web-tdesign/.env" ]; then
echo "=== .env file found ==="
cat "apps/web-tdesign/.env"
else
echo ".env file not found at apps/web-tdesign/.env"
fi
# Check for similar environment files
echo -e "\n=== Looking for related .env files ==="
find . -name ".env*" -type f 2>/dev/null | head -20
# Search for usages of VITE_APP_STORE_SECURE_KEY
echo -e "\n=== Searching for VITE_APP_STORE_SECURE_KEY usage ==="
rg -n "VITE_APP_STORE_SECURE_KEY" -A 2 -B 2Length of output: 1278
I need to check the production and development environment files to understand the full context.
🏁 Script executed:
#!/bin/bash
# Check the production and development .env files for this app
echo "=== .env.production content ==="
cat "apps/web-tdesign/.env.production" 2>/dev/null || echo "File not found"
echo -e "\n=== .env.development content ==="
cat "apps/web-tdesign/.env.development" 2>/dev/null || echo "File not found"
# Check if there's a .env.example or similar template
echo -e "\n=== Looking for .env templates or examples ==="
find ./apps/web-tdesign -name ".env*" -type f 2>/dev/null
# Check for any setup or deployment documentation
echo -e "\n=== Searching for deployment/setup docs mentioning VITE_APP_STORE_SECURE_KEY ==="
rg -l "VITE_APP_STORE_SECURE_KEY|store.*secure|encrypt.*key" --type md --type txt 2>/dev/null | head -10
# Check .gitignore to see if .env files are tracked
echo -e "\n=== Checking .gitignore for .env handling ==="
grep -n "\.env" .gitignore 2>/dev/null || echo ".gitignore not found or no .env entries"Length of output: 905
I need to check for CI/CD configuration and deployment documentation to understand the intended setup process.
🏁 Script executed:
#!/bin/bash
# Check for CI/CD configuration
echo "=== GitHub Actions workflows ==="
find .github/workflows -name "*.yml" -o -name "*.yaml" 2>/dev/null | head -5
# Check for deployment documentation
echo -e "\n=== README files ==="
find ./apps/web-tdesign -name "README*" -type f 2>/dev/null
# Check root README for deployment instructions
echo -e "\n=== Checking for deployment/env setup docs in root ==="
ls -la | grep -i readme
# Look for docker or deployment configs
echo -e "\n=== Checking for Docker or deployment configs ==="
find ./apps/web-tdesign -name "Dockerfile*" -o -name "docker-compose*" 2>/dev/null
# Search documentation folder if exists
echo -e "\n=== Checking for docs folder ==="
ls -la ./docs 2>/dev/null || echo "No docs folder"
# Check if there's any mention of environment setup in the root README
echo -e "\n=== Searching root files for environment setup guidance ==="
rg -n "environment|\.env|VITE_APP" README.md 2>/dev/null | head -20Length of output: 1211
Let me check the deployment workflow configuration to see how environment variables are handled.
🏁 Script executed:
#!/bin/bash
# Check the deploy workflow
echo "=== deploy.yml workflow ==="
cat ".github/workflows/deploy.yml"
echo -e "\n=== Checking build.yml for env handling ==="
grep -n "env:" ".github/workflows/build.yml" -A 20 | head -30Length of output: 6380
Placeholder encryption key must be replaced before production deployment.
The verification confirms this is a critical security issue. The placeholder please-replace-me-with-your-own-key in VITE_APP_STORE_SECURE_KEY is actively used in packages/stores/src/setup.ts (line 26) for AES encryption of localStorage data. The deployment workflow does not override this value, meaning production builds will use the weak placeholder key. Both .env.production and .env.development lack this configuration entry and will fall back to the base .env placeholder.
Generate or provide a strong, randomly generated encryption key and establish a deployment process that injects this via environment variables (e.g., GitHub Actions secrets or .env.local override).
| @@ -0,0 +1,35 @@ | |||
| <!doctype html> | |||
| <html lang="zh"> | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use more specific language code for Chinese.
The lang attribute uses "zh", but best practice is to specify the variant. For simplified Chinese, use "zh-CN".
-<html lang="zh">
+<html lang="zh-CN">📝 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.
| <html lang="zh"> | |
| <html lang="zh-CN"> |
🤖 Prompt for AI Agents
In apps/web-tdesign/index.html around line 2, the HTML lang attribute is
currently set to "zh"; change it to the more specific language tag "zh-CN" (for
Simplified Chinese) by updating the lang value to "zh-CN" in the <html> element
so browsers and assistive tech correctly interpret the locale.
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/vbenjs/vue-vben-admin.git", | ||
| "directory": "apps/web-naive" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix incorrect directory in repository metadata.
The directory field references "apps/web-naive" but this is the web-tdesign app. Update it to match.
"directory": "apps/web-naive"
+ "directory": "apps/web-tdesign"Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In apps/web-tdesign/package.json around line 9 the "directory" field incorrectly
points to "apps/web-naive"; update it to "apps/web-tdesign" so the repository
metadata matches this package's actual location, then save the file and run any
repo metadata validation (or lint) to ensure consistency.
| const userInfo: null | UserInfo = null; | ||
| try { | ||
| loginLoading.value = true; | ||
| const { accessToken } = await loginApi(params); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Const reassignment of userInfo breaks build. Switch to let.
- const userInfo: null | UserInfo = null;
+ let userInfo: UserInfo | null = null;
...
- userInfo = fetchUserInfoResult;
+ userInfo = fetchUserInfoResult;Also applies to: 47-50
🤖 Prompt for AI Agents
In apps/web-tdesign/src/store/auth.ts around lines 33-37 (and similarly at lines
47-50), userInfo is declared as a const but later reassigned, which breaks the
build; change the declarations from const to let so userInfo can be reassigned,
keeping the same type annotation (null | UserInfo), and verify any other
reassignment sites use the updated variable name.
| async function handleLogin(values: Recordable<any>) { | ||
| // eslint-disable-next-line no-console | ||
| console.log(values); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| // xAxis: { | ||
| // axisTick: { | ||
| // show: false, | ||
| // }, | ||
| // boundaryGap: false, | ||
| // data: Array.from({ length: 18 }).map((_item, index) => `${index + 6}:00`), | ||
| // type: 'category', | ||
| // }, |
There was a problem hiding this comment.
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.
| // 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.
| 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', | ||
| }, | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| 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.
| <AnalysisChartCard class="mt-5 md:mt-0 md:w-1/3" title="访问来源"> | ||
| <AnalyticsVisitsSales /> | ||
| </AnalysisChartCard> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
| <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.
Description
Type of change
Please delete options that are not relevant.
pnpm-lock.yamlunless you introduce a new test example.Checklist
pnpm run docs:devcommand.pnpm test.feat:,fix:,perf:,docs:, orchore:.Summary by CodeRabbit
New Features
Bug Fixes