diff --git a/.github/contributing.md b/.github/contributing.md index 9a5211b2a..f22370f3b 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -1,5 +1,42 @@ -# Contributing Guide +# Vben Admin Contributing Guide -1. Make sure you put things in the right category! -2. Always add your items to the end of a list. To be fair, the order is first-come-first-serve. -3. If you think something belongs in the wrong category, or think there needs to be a new category, feel free to edit things too. +Hi! We're really excited that you are interested in contributing to Vben Admin. Before submitting your contribution, please make sure to take a moment and read through the following guidelines: + +- [Pull Request Guidelines](#pull-request-guidelines) + +## Contributor Code of Conduct + +As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. + +We are committed to making participation in this project a harassment-free experience for everyone, regardless of the level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion. + +Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team. + +## Pull Request Guidelines + +- Checkout a topic branch from the relevant branch, e.g. main, and merge back against that branch. + +- If adding a new feature: + + - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first and have it approved before working on it. + +- If fixing bug: + + - Provide a detailed description of the bug in the PR. Live demo preferred. + +- It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging. + +## Development Setup + +You will need [pnpm](https://pnpm.io/) + +After cloning the repo, run: + +```bash +# install the dependencies of the project +$ pnpm install +# start the project +$ pnpm run dev +``` diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index 6fef16be8..fd88affe4 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -17,15 +17,17 @@ categories: - title: "🐞 Bug Fixes" labels: - "bug" + - title: "📈 Performance" + labels: + - "perf" - title: 📝 Documentation labels: - "documentation" - title: 👻 Maintenance labels: - - "perf" - "chore" - "dependencies" - collapse-after: 5 + # collapse-after: 12 - title: 🚦 Tests labels: - "tests" @@ -40,11 +42,10 @@ version-resolver: minor: labels: - "minor" - # - "feature" + - "feature" patch: labels: - "patch" - - "feature" - "bug" - "maintenance" - "docs" diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9832a9002..08ff80b7d 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -6,8 +6,47 @@ on: - main jobs: - deploy-push-ftp: - name: Deploy Push Ftp + deploy-push-playground-ftp: + name: Deploy Push Playground Ftp + if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Sed Config Base + shell: bash + run: | + sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./playground/.env.production + sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./playground/.env.production + cat ./playground/.env.production + + - name: Setup Node + uses: ./.github/actions/setup-node + + - name: Build + run: pnpm run build + + - name: Sync Playground files + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.PRO_FTP_HOST }} + username: ${{ secrets.WEB_PLAYGROUND_FTP_ACCOUNT }} + password: ${{ secrets.WEB_PLAYGROUND_FTP_PWSSWORD }} + local-dir: ./playground/dist/ + + - name: Sync Docs files + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.PRO_FTP_HOST }} + username: ${{ secrets.WEBSITE_FTP_ACCOUNT }} + password: ${{ secrets.WEBSITE_FTP_PASSWORD }} + local-dir: ./docs/.vitepress/dist/ + + deploy-push-antd-ftp: + name: Deploy Push Antd Ftp if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') runs-on: ubuntu-latest steps: @@ -22,9 +61,65 @@ jobs: sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-antd/.env.production sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-antd/.env.production cat ./apps/web-antd/.env.production + + - name: Setup Node + uses: ./.github/actions/setup-node + + - name: Build + run: pnpm run build + + - name: Sync files + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.PRO_FTP_HOST }} + username: ${{ secrets.WEB_ANTD_FTP_ACCOUNT }} + password: ${{ secrets.WEB_ANTD_FTP_PASSWORD }} + local-dir: ./apps/web-antd/dist/ + + deploy-push-ele-ftp: + name: Deploy Push Element Ftp + if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Sed Config Base + shell: bash + run: | sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-ele/.env.production sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-ele/.env.production cat ./apps/web-ele/.env.production + + - name: Setup Node + uses: ./.github/actions/setup-node + + - name: Build + run: pnpm run build + + - name: Sync files + uses: SamKirkland/FTP-Deploy-Action@v4.3.5 + with: + server: ${{ secrets.PRO_FTP_HOST }} + username: ${{ secrets.WEB_ELE_FTP_ACCOUNT }} + password: ${{ secrets.WEB_ELE_FTP_PASSWORD }} + local-dir: ./apps/web-ele/dist/ + + deploy-push-naive-ftp: + name: Deploy Push Naive Ftp + if: github.actor != 'dependabot[bot]' && !contains(github.event.head_commit.message, '[skip ci]') + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Sed Config Base + shell: bash + run: | sed -i "s#VITE_COMPRESS\s*=.*#VITE_COMPRESS = gzip#g" ./apps/web-naive/.env.production sed -i "s#VITE_PWA\s*=.*#VITE_PWA = true#g" ./apps/web-naive/.env.production cat ./apps/web-naive/.env.production @@ -35,34 +130,10 @@ jobs: - name: Build run: pnpm run build - - name: Sync Web Antd files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 - with: - server: ${{ secrets.PRO_FTP_HOST }} - username: ${{ secrets.WEB_ANTD_FTP_ACCOUNT }} - password: ${{ secrets.WEB_ANTD_FTP_PASSWORD }} - local-dir: ./apps/web-antd/dist/ - - - name: Sync Web Naive files + - name: Sync files uses: SamKirkland/FTP-Deploy-Action@v4.3.5 with: server: ${{ secrets.PRO_FTP_HOST }} username: ${{ secrets.WEB_NAIVE_FTP_ACCOUNT }} password: ${{ secrets.WEB_NAIVE_FTP_PASSWORD }} local-dir: ./apps/web-naive/dist/ - - - name: Sync Web Ele files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 - with: - server: ${{ secrets.PRO_FTP_HOST }} - username: ${{ secrets.WEB_ELE_FTP_ACCOUNT }} - password: ${{ secrets.WEB_ELE_FTP_PASSWORD }} - local-dir: ./apps/web-ele/dist/ - - - name: Sync Docs files - uses: SamKirkland/FTP-Deploy-Action@v4.3.5 - with: - server: ${{ secrets.PRO_FTP_HOST }} - username: ${{ secrets.WEBSITE_FTP_ACCOUNT }} - password: ${{ secrets.WEBSITE_FTP_PASSWORD }} - local-dir: ./docs/.vitepress/dist/ diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a0fec0000..cf48052d5 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -10,10 +10,6 @@ "esbenp.prettier-vscode", // 支持 dotenv 文件语法 "mikestead.dotenv", - // 获取每个 CSS 属性的初始值。 - "dzhavat.css-initial-value", - // 使 VSCode 中的 TypeScript 错误更漂亮、更易于理解 - "yoavbls.pretty-ts-errors", // 源代码的拼写检查器 "streetsidesoftware.code-spell-checker", // Tailwind CSS 的官方 VS Code 插件 diff --git a/.vscode/launch.json b/.vscode/launch.json index 08bd54f0d..3b4e323c1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,18 +4,27 @@ "configurations": [ { "type": "chrome", - "name": "vben admin antd dev", + "name": "vben admin playground dev", "request": "launch", "url": "http://localhost:5555", "env": { "NODE_ENV": "development" }, "sourceMaps": true, + "webRoot": "${workspaceFolder}/playground/src" + }, + { + "type": "chrome", + "name": "vben admin antd dev", + "request": "launch", + "url": "http://localhost:5666", + "env": { "NODE_ENV": "development" }, + "sourceMaps": true, "webRoot": "${workspaceFolder}/apps/web-antd/src" }, { "type": "chrome", "name": "vben admin ele dev", "request": "launch", - "url": "http://localhost:5666", + "url": "http://localhost:5777", "env": { "NODE_ENV": "development" }, "sourceMaps": true, "webRoot": "${workspaceFolder}/apps/web-ele/src" @@ -24,7 +33,7 @@ "type": "chrome", "name": "vben admin naive dev", "request": "launch", - "url": "http://localhost:5777", + "url": "http://localhost:5888", "env": { "NODE_ENV": "development" }, "sourceMaps": true, "webRoot": "${workspaceFolder}/apps/web-naive/src" diff --git a/.vscode/settings.json b/.vscode/settings.json index eb3f43d52..38a9c5e27 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -167,6 +167,7 @@ "i18n-ally.localesPaths": [ "packages/locales/src/langs", + "playground/src/langs", "apps/*/src/locales/langs" ], "i18n-ally.enabledParsers": ["json", "ts", "js", "yaml"], @@ -191,5 +192,6 @@ "i18n-ally.keystyle": "nested", "commentTranslate.multiLineMerge": true, "vue.server.hybridMode": true, - "typescript.tsdk": "node_modules/typescript/lib" + "typescript.tsdk": "node_modules/typescript/lib", + "vitest.disableWorkspaceWarning": true } diff --git a/Dockerfile b/Dockerfile index 4b76d886c..61076b6dc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,7 +21,7 @@ RUN echo "Builder Success 🎉" FROM nginx:stable-alpine as production RUN echo "types { application/javascript js mjs; }" > /etc/nginx/conf.d/mjs.conf -COPY --from=builder /app/apps/web-antd/dist /usr/share/nginx/html +COPY --from=builder /app/playground/dist /usr/share/nginx/html COPY ./nginx.conf /etc/nginx/nginx.conf diff --git a/README.ja-JP.md b/README.ja-JP.md index f794c792a..700f8357f 100644 --- a/README.ja-JP.md +++ b/README.ja-JP.md @@ -134,7 +134,8 @@ pnpm build ## 貢献者 - + Contributors ## Discord diff --git a/README.md b/README.md index 5ce954bc0..7cf502ed1 100644 --- a/README.md +++ b/README.md @@ -133,7 +133,8 @@ If you think this project is helpful to you, you can help the author buy a cup o ## Contributor - + Contributors ## Discord diff --git a/README.zh-CN.md b/README.zh-CN.md index 9137ef6eb..73e8fbeb9 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -126,6 +126,13 @@ pnpm build Paypal Me +## Contributor + + + Contributors + + ## Discord - [Github Discussions](https://github.com/anncwb/vue-vben-admin/discussions) diff --git a/apps/web-antd/.env b/apps/web-antd/.env index 87821d87c..c14a467fb 100644 --- a/apps/web-antd/.env +++ b/apps/web-antd/.env @@ -1,5 +1,5 @@ # 应用标题 -VITE_APP_TITLE=Vben Admin +VITE_APP_TITLE=Vben Admin Antd # 应用命名空间,用于缓存、store等功能的前缀,确保隔离 VITE_APP_NAMESPACE=vben-web-antd diff --git a/apps/web-antd/.env.development b/apps/web-antd/.env.development index c27e90c4e..25e2e2fcd 100644 --- a/apps/web-antd/.env.development +++ b/apps/web-antd/.env.development @@ -1,6 +1,6 @@ # 端口号 -VITE_PORT=5555 -# base路径 +VITE_PORT=5666 + VITE_BASE=/ # 是否开启 Nitro Mock服务,true 为开启,false 为关闭 VITE_NITRO_MOCK=true diff --git a/apps/web-antd/src/api/index.ts b/apps/web-antd/src/api/index.ts index 2b42e898a..4b0e04137 100644 --- a/apps/web-antd/src/api/index.ts +++ b/apps/web-antd/src/api/index.ts @@ -1,2 +1 @@ export * from './core'; -export * from './demos'; diff --git a/apps/web-antd/src/locales/index.ts b/apps/web-antd/src/locales/index.ts index a3e23661e..1751f4e5e 100644 --- a/apps/web-antd/src/locales/index.ts +++ b/apps/web-antd/src/locales/index.ts @@ -58,7 +58,11 @@ async function loadDayjsLocale(lang: SupportedLanguagesType) { locale = await import('dayjs/locale/en'); } } - dayjs.locale(locale); + if (locale) { + dayjs.locale(locale); + } else { + console.error(`Failed to load dayjs locale for ${lang}`); + } } /** diff --git a/apps/web-antd/src/locales/langs/en-US.json b/apps/web-antd/src/locales/langs/en-US.json index 13179fd2c..864c721f5 100644 --- a/apps/web-antd/src/locales/langs/en-US.json +++ b/apps/web-antd/src/locales/langs/en-US.json @@ -2,66 +2,7 @@ "page": { "demos": { "title": "Demos", - "access": { - "frontendPermissions": "Frontend Permissions", - "backendPermissions": "Backend Permissions", - "pageAccess": "Page Access", - "buttonControl": "Button Control", - "menuVisible403": "Menu Visible(403)", - "superVisible": "Visible to Super", - "adminVisible": "Visible to Admin", - "userVisible": "Visible to User" - }, - "nested": { - "title": "Nested Menu", - "menu1": "Menu 1", - "menu2": "Menu 2", - "menu2_1": "Menu 2-1", - "menu3": "Menu 3", - "menu3_1": "Menu 3-1", - "menu3_2": "Menu 3-2", - "menu3_2_1": "Menu 3-2-1" - }, - "outside": { - "title": "External Pages", - "embedded": "Embedded", - "externalLink": "External Link" - }, - "badge": { - "title": "Menu Badge", - "dot": "Dot Badge", - "text": "Text Badge", - "color": "Badge Color" - }, - "activeIcon": { - "title": "Active Menu Icon", - "children": "Children Active Icon" - }, - "fallback": { - "title": "Fallback Page" - }, - "features": { - "title": "Features", - "hideChildrenInMenu": "Hide Menu Children", - "loginExpired": "Login Expired", - "icons": "Icons", - "watermark": "Watermark", - "tabs": "Tabs", - "tabDetail": "Tab Detail Page" - }, - "breadcrumb": { - "navigation": "Breadcrumb Navigation", - "lateral": "Lateral Mode", - "lateralDetail": "Lateral Mode Detail", - "level": "Level Mode", - "levelDetail": "Level Mode Detail" - } - }, - "examples": { - "title": "Examples", - "ellipsis": { - "title": "EllipsisText" - } + "antd": "Ant Design Vue" } } } diff --git a/apps/web-antd/src/locales/langs/zh-CN.json b/apps/web-antd/src/locales/langs/zh-CN.json index 86fbcabcf..31d3475b9 100644 --- a/apps/web-antd/src/locales/langs/zh-CN.json +++ b/apps/web-antd/src/locales/langs/zh-CN.json @@ -2,66 +2,7 @@ "page": { "demos": { "title": "演示", - "access": { - "frontendPermissions": "前端权限", - "backendPermissions": "后端权限", - "pageAccess": "页面访问", - "buttonControl": "按钮控制", - "menuVisible403": "菜单可见(403)", - "superVisible": "Super 可见", - "adminVisible": "Admin 可见", - "userVisible": "User 可见" - }, - "nested": { - "title": "嵌套菜单", - "menu1": "菜单 1", - "menu2": "菜单 2", - "menu2_1": "菜单 2-1", - "menu3": "菜单 3", - "menu3_1": "菜单 3-1", - "menu3_2": "菜单 3-2", - "menu3_2_1": "菜单 3-2-1" - }, - "outside": { - "title": "外部页面", - "embedded": "内嵌", - "externalLink": "外链" - }, - "badge": { - "title": "菜单徽标", - "dot": "点徽标", - "text": "文本徽标", - "color": "徽标颜色" - }, - "activeIcon": { - "title": "菜单激活图标", - "children": "子级激活图标" - }, - "fallback": { - "title": "缺省页" - }, - "features": { - "title": "功能", - "hideChildrenInMenu": "隐藏子菜单", - "loginExpired": "登录过期", - "icons": "图标", - "watermark": "水印", - "tabs": "标签页", - "tabDetail": "标签详情页" - }, - "breadcrumb": { - "navigation": "面包屑导航", - "lateral": "平级模式", - "level": "层级模式", - "levelDetail": "层级模式详情", - "lateralDetail": "平级模式详情" - } - }, - "examples": { - "title": "示例", - "ellipsis": { - "title": "文本省略" - } + "antd": "Ant Design Vue" } } } diff --git a/apps/web-antd/src/router/guard.ts b/apps/web-antd/src/router/guard.ts index 1581d0151..f6b79f06c 100644 --- a/apps/web-antd/src/router/guard.ts +++ b/apps/web-antd/src/router/guard.ts @@ -115,10 +115,10 @@ function setupAccessGuard(router: Router) { // 保存菜单信息和路由信息 accessStore.setAccessMenus(accessibleMenus); accessStore.setAccessRoutes(accessibleRoutes); - const redirectPath = (from.query.redirect ?? to.path) as string; + const redirectPath = (from.query.redirect ?? to.fullPath) as string; return { - path: decodeURIComponent(redirectPath), + ...router.resolve(decodeURIComponent(redirectPath)), replace: true, }; }); diff --git a/apps/web-antd/src/router/routes/modules/demos.ts b/apps/web-antd/src/router/routes/modules/demos.ts index ad88a5486..fa28acc76 100644 --- a/apps/web-antd/src/router/routes/modules/demos.ts +++ b/apps/web-antd/src/router/routes/modules/demos.ts @@ -1,6 +1,6 @@ import type { RouteRecordRaw } from 'vue-router'; -import { BasicLayout, IFrameView } from '#/layouts'; +import { BasicLayout } from '#/layouts'; import { $t } from '#/locales'; const routes: RouteRecordRaw[] = [ @@ -15,477 +15,13 @@ const routes: RouteRecordRaw[] = [ name: 'Demos', path: '/demos', children: [ - // 权限控制 { meta: { - icon: 'mdi:shield-key-outline', - title: $t('page.demos.access.frontendPermissions'), + title: $t('page.demos.antd'), }, - name: 'AccessDemos', - path: '/demos/access', - children: [ - { - name: 'AccessPageControlDemo', - path: '/demos/access/page-control', - component: () => import('#/views/demos/access/index.vue'), - meta: { - icon: 'mdi:page-previous-outline', - title: $t('page.demos.access.pageAccess'), - }, - }, - { - name: 'AccessButtonControlDemo', - path: '/demos/access/button-control', - component: () => import('#/views/demos/access/button-control.vue'), - meta: { - icon: 'mdi:button-cursor', - title: $t('page.demos.access.buttonControl'), - }, - }, - { - name: 'AccessMenuVisible403Demo', - path: '/demos/access/menu-visible-403', - component: () => - import('#/views/demos/access/menu-visible-403.vue'), - meta: { - authority: ['no-body'], - icon: 'mdi:button-cursor', - menuVisibleWithForbidden: true, - title: $t('page.demos.access.menuVisible403'), - }, - }, - { - name: 'AccessSuperVisibleDemo', - path: '/demos/access/super-visible', - component: () => import('#/views/demos/access/super-visible.vue'), - meta: { - authority: ['super'], - icon: 'mdi:button-cursor', - title: $t('page.demos.access.superVisible'), - }, - }, - { - name: 'AccessAdminVisibleDemo', - path: '/demos/access/admin-visible', - component: () => import('#/views/demos/access/admin-visible.vue'), - meta: { - authority: ['admin'], - icon: 'mdi:button-cursor', - title: $t('page.demos.access.adminVisible'), - }, - }, - { - name: 'AccessUserVisibleDemo', - path: '/demos/access/user-visible', - component: () => import('#/views/demos/access/user-visible.vue'), - meta: { - authority: ['user'], - icon: 'mdi:button-cursor', - title: $t('page.demos.access.userVisible'), - }, - }, - ], - }, - // 功能 - { - meta: { - icon: 'mdi:feature-highlight', - title: $t('page.demos.features.title'), - }, - name: 'FeaturesDemos', - path: '/demos/features', - children: [ - { - name: 'LoginExpiredDemo', - path: '/demos/features/login-expired', - component: () => - import('#/views/demos/features/login-expired/index.vue'), - meta: { - icon: 'mdi:encryption-expiration', - title: $t('page.demos.features.loginExpired'), - }, - }, - { - name: 'IconsDemo', - path: '/demos/features/icons', - component: () => import('#/views/demos/features/icons/index.vue'), - meta: { - title: $t('page.demos.features.icons'), - }, - }, - { - name: 'WatermarkDemo', - path: '/demos/features/watermark', - component: () => - import('#/views/demos/features/watermark/index.vue'), - meta: { - title: $t('page.demos.features.watermark'), - }, - }, - { - name: 'FeatureTabsDemo', - path: '/demos/features/tabs', - component: () => import('#/views/demos/features/tabs/index.vue'), - meta: { - icon: 'lucide:app-window', - title: $t('page.demos.features.tabs'), - }, - }, - { - name: 'FeatureTabDetailDemo', - path: '/demos/features/tabs/detail/:id', - component: () => - import('#/views/demos/features/tabs/tab-detail.vue'), - meta: { - activePath: '/demos/features/tabs', - hideInMenu: true, - maxNumOfOpenTab: 3, - title: $t('page.demos.features.tabDetail'), - }, - }, - { - name: 'HideChildrenInMenuParentDemo', - path: '/demos/features/hide-menu-children', - component: () => - import('#/views/demos/features/hide-menu-children/parent.vue'), - meta: { - hideChildrenInMenu: true, - icon: 'ic:round-menu', - title: $t('page.demos.features.hideChildrenInMenu'), - }, - children: [ - { - name: 'HideChildrenInMenuChildrenDemo', - path: '/demos/features/hide-menu-children/children', - component: () => - import( - '#/views/demos/features/hide-menu-children/children.vue' - ), - meta: { title: 'HideChildrenInMenuChildrenDemo' }, - }, - ], - }, - ], - }, - // 面包屑导航 - { - name: 'BreadcrumbDemos', - path: '/demos/breadcrumb', - meta: { - icon: 'lucide:navigation', - title: $t('page.demos.breadcrumb.navigation'), - }, - children: [ - { - name: 'BreadcrumbLateralDemo', - path: '/demos/breadcrumb/lateral', - component: () => import('#/views/demos/breadcrumb/lateral.vue'), - meta: { - icon: 'lucide:navigation', - title: $t('page.demos.breadcrumb.lateral'), - }, - }, - { - name: 'BreadcrumbLateralDetailDemo', - path: '/demos/breadcrumb/lateral-detail', - component: () => - import('#/views/demos/breadcrumb/lateral-detail.vue'), - meta: { - activePath: '/demos/breadcrumb/lateral', - hideInMenu: true, - title: $t('page.demos.breadcrumb.lateralDetail'), - }, - }, - { - name: 'BreadcrumbLevelDemo', - path: '/demos/breadcrumb/level', - meta: { - icon: 'lucide:navigation', - title: $t('page.demos.breadcrumb.level'), - }, - children: [ - { - name: 'BreadcrumbLevelDetailDemo', - path: '/demos/breadcrumb/level/detail', - component: () => - import('#/views/demos/breadcrumb/level-detail.vue'), - meta: { - title: $t('page.demos.breadcrumb.levelDetail'), - }, - }, - ], - }, - ], - }, - // 缺省页 - { - meta: { - icon: 'mdi:lightbulb-error-outline', - title: $t('page.demos.fallback.title'), - }, - name: 'FallbackDemos', - path: '/demos/fallback', - children: [ - { - name: 'Fallback403Demo', - path: '/demos/fallback/403', - component: () => import('#/views/_core/fallback/forbidden.vue'), - meta: { - icon: 'mdi:do-not-disturb-alt', - title: '403', - }, - }, - { - name: 'Fallback404Demo', - path: '/demos/fallback/404', - component: () => import('#/views/_core/fallback/not-found.vue'), - meta: { - icon: 'mdi:table-off', - title: '404', - }, - }, - { - name: 'Fallback500Demo', - path: '/demos/fallback/500', - component: () => - import('#/views/_core/fallback/internal-error.vue'), - meta: { - icon: 'mdi:server-network-off', - title: '500', - }, - }, - { - name: 'FallbackOfflineDemo', - path: '/demos/fallback/offline', - component: () => import('#/views/_core/fallback/offline.vue'), - meta: { - icon: 'mdi:offline', - title: $t('fallback.offline'), - }, - }, - ], - }, - // 菜单徽标 - { - meta: { - badgeType: 'dot', - badgeVariants: 'destructive', - icon: 'lucide:circle-dot', - title: $t('page.demos.badge.title'), - }, - name: 'BadgeDemos', - path: '/demos/badge', - children: [ - { - name: 'BadgeDotDemo', - component: () => import('#/views/demos/badge/index.vue'), - path: '/demos/badge/dot', - meta: { - badgeType: 'dot', - icon: 'lucide:square-dot', - title: $t('page.demos.badge.dot'), - }, - }, - { - name: 'BadgeTextDemo', - component: () => import('#/views/demos/badge/index.vue'), - path: '/demos/badge/text', - meta: { - badge: '10', - icon: 'lucide:square-dot', - title: $t('page.demos.badge.text'), - }, - }, - { - name: 'BadgeColorDemo', - component: () => import('#/views/demos/badge/index.vue'), - path: '/demos/badge/color', - meta: { - badge: 'Hot', - badgeVariants: 'destructive', - icon: 'lucide:square-dot', - title: $t('page.demos.badge.color'), - }, - }, - ], - }, - // 菜单激活图标 - { - meta: { - activeIcon: 'fluent-emoji:radioactive', - icon: 'bi:radioactive', - title: $t('page.demos.activeIcon.title'), - }, - name: 'ActiveIconDemos', - path: '/demos/active-icon', - children: [ - { - name: 'ActiveIconDemo', - component: () => import('#/views/demos/active-icon/index.vue'), - path: '/demos/active-icon/children', - meta: { - activeIcon: 'fluent-emoji:radioactive', - icon: 'bi:radioactive', - title: $t('page.demos.activeIcon.children'), - }, - }, - ], - }, - // 外部链接 - { - meta: { - icon: 'ic:round-settings-input-composite', - title: $t('page.demos.outside.title'), - }, - name: 'OutsideDemos', - path: '/demos/outside', - children: [ - { - name: 'IframeDemos', - path: '/demos/outside/iframe', - meta: { - icon: 'mdi:newspaper-variant-outline', - title: $t('page.demos.outside.embedded'), - }, - children: [ - { - name: 'VueDocumentDemo', - path: '/demos/outside/iframe/vue-document', - component: IFrameView, - meta: { - icon: 'logos:vue', - iframeSrc: 'https://cn.vuejs.org/', - keepAlive: true, - title: 'Vue', - }, - }, - { - name: 'TailwindcssDemo', - path: '/demos/outside/iframe/tailwindcss', - component: IFrameView, - meta: { - icon: 'devicon:tailwindcss', - iframeSrc: 'https://tailwindcss.com/', - // keepAlive: true, - title: 'Tailwindcss', - }, - }, - ], - }, - { - name: 'ExternalLinkDemos', - path: '/demos/outside/external-link', - meta: { - icon: 'mdi:newspaper-variant-multiple-outline', - title: $t('page.demos.outside.externalLink'), - }, - children: [ - { - name: 'ViteDemo', - path: '/demos/outside/external-link/vite', - component: IFrameView, - meta: { - icon: 'logos:vitejs', - link: 'https://vitejs.dev/', - title: 'Vite', - }, - }, - { - name: 'VueUseDemo', - path: '/demos/outside/external-link/vue-use', - component: IFrameView, - meta: { - icon: 'logos:vueuse', - link: 'https://vueuse.org', - title: 'VueUse', - }, - }, - ], - }, - ], - }, - // 嵌套菜单 - { - meta: { - icon: 'ic:round-menu', - title: $t('page.demos.nested.title'), - }, - name: 'NestedDemos', - path: '/demos/nested', - children: [ - { - name: 'Menu1Demo', - path: '/demos/nested/menu1', - component: () => import('#/views/demos/nested/menu-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('page.demos.nested.menu1'), - }, - }, - { - name: 'Menu2Demo', - path: '/demos/nested/menu2', - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('page.demos.nested.menu2'), - }, - children: [ - { - name: 'Menu21Demo', - path: '/demos/nested/menu2/menu2-1', - component: () => import('#/views/demos/nested/menu-2-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('page.demos.nested.menu2_1'), - }, - }, - ], - }, - { - name: 'Menu3Demo', - path: '/demos/nested/menu3', - meta: { - icon: 'ic:round-menu', - title: $t('page.demos.nested.menu3'), - }, - children: [ - { - name: 'Menu31Demo', - path: 'menu3-1', - component: () => import('#/views/demos/nested/menu-3-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('page.demos.nested.menu3_1'), - }, - }, - { - name: 'Menu32Demo', - path: 'menu3-2', - meta: { - icon: 'ic:round-menu', - title: $t('page.demos.nested.menu3_2'), - }, - children: [ - { - name: 'Menu321Demo', - path: '/demos/nested/menu3/menu3-2/menu3-2-1', - component: () => - import('#/views/demos/nested/menu-3-2-1.vue'), - meta: { - icon: 'ic:round-menu', - keepAlive: true, - title: $t('page.demos.nested.menu3_2_1'), - }, - }, - ], - }, - ], - }, - ], + name: 'AntDesignDemos', + path: '/demos/ant-design', + component: () => import('#/views/demos/antd/index.vue'), }, ], }, diff --git a/apps/web-antd/src/router/routes/modules/vben.ts b/apps/web-antd/src/router/routes/modules/vben.ts index 3a0daabe3..48e38fb2e 100644 --- a/apps/web-antd/src/router/routes/modules/vben.ts +++ b/apps/web-antd/src/router/routes/modules/vben.ts @@ -38,8 +38,7 @@ const routes: RouteRecordRaw[] = [ component: IFrameView, meta: { icon: 'lucide:book-open-text', - iframeSrc: VBEN_DOC_URL, - keepAlive: true, + link: VBEN_DOC_URL, title: $t('page.vben.document'), }, }, diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue index 1bef4d4ec..261c847ce 100644 --- a/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue +++ b/apps/web-antd/src/views/dashboard/analytics/analytics-trends.vue @@ -13,7 +13,7 @@ onMounted(() => { containLabel: true, left: '1%', right: '1%', - top: '2 %', + top: '2 %', }, series: [ { diff --git a/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue index 4dfc163fd..8230f6e5c 100644 --- a/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue +++ b/apps/web-antd/src/views/dashboard/analytics/analytics-visits.vue @@ -13,7 +13,7 @@ onMounted(() => { containLabel: true, left: '1%', right: '1%', - top: '2 %', + top: '2 %', }, series: [ { diff --git a/apps/web-antd/src/views/demos/antd/index.vue b/apps/web-antd/src/views/demos/antd/index.vue new file mode 100644 index 000000000..8286bebb1 --- /dev/null +++ b/apps/web-antd/src/views/demos/antd/index.vue @@ -0,0 +1,66 @@ + + + diff --git a/apps/web-antd/src/views/examples/ellipsis/data.ts b/apps/web-antd/src/views/examples/ellipsis/data.ts deleted file mode 100644 index 796d95a7e..000000000 --- a/apps/web-antd/src/views/examples/ellipsis/data.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const longText: string = - 'Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。Vben Admin 是一个基于 Vue3.0、Vite、 TypeScript 的后台解决方案,目标是为开发中大型项目提供开箱即用的解决方案。包括二次封装组件、utils、hooks、动态菜单、权限校验、多主题配置、按钮级别权限控制等功能。项目会使用前端较新的技术栈,可以作为项目的启动模版,以帮助你快速搭建企业级中后台产品原型。也可以作为一个示例,用于学习 vue3、vite、ts 等主流技术。该项目会持续跟进最新技术,并将其应用在项目中。'; diff --git a/apps/web-antd/src/views/examples/ellipsis/index.vue b/apps/web-antd/src/views/examples/ellipsis/index.vue deleted file mode 100644 index 6c501bad4..000000000 --- a/apps/web-antd/src/views/examples/ellipsis/index.vue +++ /dev/null @@ -1,42 +0,0 @@ - - - diff --git a/apps/web-ele/.env.development b/apps/web-ele/.env.development index c138f4829..8bcb432e6 100644 --- a/apps/web-ele/.env.development +++ b/apps/web-ele/.env.development @@ -1,5 +1,5 @@ # 端口号 -VITE_PORT=5666 +VITE_PORT=5777 VITE_BASE=/ diff --git a/apps/web-ele/src/api/request.ts b/apps/web-ele/src/api/request.ts index ac6c0f9b6..dd7816508 100644 --- a/apps/web-ele/src/api/request.ts +++ b/apps/web-ele/src/api/request.ts @@ -59,7 +59,7 @@ function createRequestClient(baseURL: string) { if (status >= 200 && status < 400 && code === 0) { return data; } - throw new Error(msg); + throw new Error(`Error ${status}: ${msg}`); }); return client; } diff --git a/apps/web-ele/src/locales/index.ts b/apps/web-ele/src/locales/index.ts index 186935e09..695cff56e 100644 --- a/apps/web-ele/src/locales/index.ts +++ b/apps/web-ele/src/locales/index.ts @@ -58,7 +58,11 @@ async function loadDayjsLocale(lang: SupportedLanguagesType) { locale = await import('dayjs/locale/en'); } } - dayjs.locale(locale); + if (locale) { + dayjs.locale(locale); + } else { + console.error(`Failed to load dayjs locale for ${lang}`); + } } /** diff --git a/apps/web-ele/src/router/guard.ts b/apps/web-ele/src/router/guard.ts index 1581d0151..f6b79f06c 100644 --- a/apps/web-ele/src/router/guard.ts +++ b/apps/web-ele/src/router/guard.ts @@ -115,10 +115,10 @@ function setupAccessGuard(router: Router) { // 保存菜单信息和路由信息 accessStore.setAccessMenus(accessibleMenus); accessStore.setAccessRoutes(accessibleRoutes); - const redirectPath = (from.query.redirect ?? to.path) as string; + const redirectPath = (from.query.redirect ?? to.fullPath) as string; return { - path: decodeURIComponent(redirectPath), + ...router.resolve(decodeURIComponent(redirectPath)), replace: true, }; }); diff --git a/apps/web-ele/src/router/routes/modules/demos.ts b/apps/web-ele/src/router/routes/modules/demos.ts index 25a58989a..7b638a998 100644 --- a/apps/web-ele/src/router/routes/modules/demos.ts +++ b/apps/web-ele/src/router/routes/modules/demos.ts @@ -17,7 +17,6 @@ const routes: RouteRecordRaw[] = [ children: [ { meta: { - icon: 'mdi:shield-key-outline', title: $t('page.demos.element-plus'), }, name: 'NaiveDemos', diff --git a/apps/web-ele/src/router/routes/modules/vben.ts b/apps/web-ele/src/router/routes/modules/vben.ts index a5ced040e..3a8f2e942 100644 --- a/apps/web-ele/src/router/routes/modules/vben.ts +++ b/apps/web-ele/src/router/routes/modules/vben.ts @@ -1,11 +1,11 @@ import type { RouteRecordRaw } from 'vue-router'; import { + VBEN_ANT_PREVIEW_URL, VBEN_DOC_URL, VBEN_GITHUB_URL, VBEN_LOGO_URL, VBEN_NAIVE_PREVIEW_URL, - VBEN_PREVIEW_URL, } from '@vben/constants'; import { BasicLayout, IFrameView } from '#/layouts'; @@ -38,8 +38,7 @@ const routes: RouteRecordRaw[] = [ component: IFrameView, meta: { icon: 'lucide:book-open-text', - iframeSrc: VBEN_DOC_URL, - keepAlive: true, + link: VBEN_DOC_URL, title: $t('page.vben.document'), }, }, @@ -69,7 +68,7 @@ const routes: RouteRecordRaw[] = [ component: IFrameView, meta: { badgeType: 'dot', - link: VBEN_PREVIEW_URL, + link: VBEN_ANT_PREVIEW_URL, title: $t('page.vben.antdv'), }, }, diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue index 1bef4d4ec..261c847ce 100644 --- a/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue +++ b/apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue @@ -13,7 +13,7 @@ onMounted(() => { containLabel: true, left: '1%', right: '1%', - top: '2 %', + top: '2 %', }, series: [ { diff --git a/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue index 4dfc163fd..8230f6e5c 100644 --- a/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue +++ b/apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue @@ -13,7 +13,7 @@ onMounted(() => { containLabel: true, left: '1%', right: '1%', - top: '2 %', + top: '2 %', }, series: [ { diff --git a/apps/web-ele/src/views/demos/element/index.vue b/apps/web-ele/src/views/demos/element/index.vue index 15f0d5e39..dc02759ff 100644 --- a/apps/web-ele/src/views/demos/element/index.vue +++ b/apps/web-ele/src/views/demos/element/index.vue @@ -1,4 +1,6 @@ diff --git a/apps/web-naive/.env.development b/apps/web-naive/.env.development index 8bcb432e6..11c5254ae 100644 --- a/apps/web-naive/.env.development +++ b/apps/web-naive/.env.development @@ -1,5 +1,5 @@ # 端口号 -VITE_PORT=5777 +VITE_PORT=5888 VITE_BASE=/ diff --git a/apps/web-naive/src/api/request.ts b/apps/web-naive/src/api/request.ts index 524576be5..6ebd6d930 100644 --- a/apps/web-naive/src/api/request.ts +++ b/apps/web-naive/src/api/request.ts @@ -58,7 +58,7 @@ function createRequestClient(baseURL: string) { if (status >= 200 && status < 400 && code === 0) { return data; } - throw new Error(msg); + throw new Error(`Error ${status}: ${msg}`); }); return client; } diff --git a/apps/web-naive/src/router/guard.ts b/apps/web-naive/src/router/guard.ts index 1581d0151..f6b79f06c 100644 --- a/apps/web-naive/src/router/guard.ts +++ b/apps/web-naive/src/router/guard.ts @@ -115,10 +115,10 @@ function setupAccessGuard(router: Router) { // 保存菜单信息和路由信息 accessStore.setAccessMenus(accessibleMenus); accessStore.setAccessRoutes(accessibleRoutes); - const redirectPath = (from.query.redirect ?? to.path) as string; + const redirectPath = (from.query.redirect ?? to.fullPath) as string; return { - path: decodeURIComponent(redirectPath), + ...router.resolve(decodeURIComponent(redirectPath)), replace: true, }; }); diff --git a/apps/web-naive/src/router/routes/modules/demos.ts b/apps/web-naive/src/router/routes/modules/demos.ts index 8ddf81eb4..5a2dc12a0 100644 --- a/apps/web-naive/src/router/routes/modules/demos.ts +++ b/apps/web-naive/src/router/routes/modules/demos.ts @@ -17,7 +17,6 @@ const routes: RouteRecordRaw[] = [ children: [ { meta: { - icon: 'mdi:shield-key-outline', title: $t('page.demos.naive'), }, name: 'NaiveDemos', diff --git a/apps/web-naive/src/router/routes/modules/vben.ts b/apps/web-naive/src/router/routes/modules/vben.ts index 3fd5942b5..0b1273df6 100644 --- a/apps/web-naive/src/router/routes/modules/vben.ts +++ b/apps/web-naive/src/router/routes/modules/vben.ts @@ -1,11 +1,11 @@ import type { RouteRecordRaw } from 'vue-router'; import { + VBEN_ANT_PREVIEW_URL, VBEN_DOC_URL, VBEN_ELE_PREVIEW_URL, VBEN_GITHUB_URL, VBEN_LOGO_URL, - VBEN_PREVIEW_URL, } from '@vben/constants'; import { BasicLayout, IFrameView } from '#/layouts'; @@ -38,8 +38,7 @@ const routes: RouteRecordRaw[] = [ component: IFrameView, meta: { icon: 'lucide:book-open-text', - iframeSrc: VBEN_DOC_URL, - keepAlive: true, + link: VBEN_DOC_URL, title: $t('page.vben.document'), }, }, @@ -59,7 +58,7 @@ const routes: RouteRecordRaw[] = [ component: IFrameView, meta: { badgeType: 'dot', - link: VBEN_PREVIEW_URL, + link: VBEN_ANT_PREVIEW_URL, title: $t('page.vben.antdv'), }, }, diff --git a/apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue b/apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue index 1bef4d4ec..261c847ce 100644 --- a/apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue +++ b/apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue @@ -13,7 +13,7 @@ onMounted(() => { containLabel: true, left: '1%', right: '1%', - top: '2 %', + top: '2 %', }, series: [ { diff --git a/apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue b/apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue index 4dfc163fd..8230f6e5c 100644 --- a/apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue +++ b/apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue @@ -13,7 +13,7 @@ onMounted(() => { containLabel: true, left: '1%', right: '1%', - top: '2 %', + top: '2 %', }, series: [ { diff --git a/apps/web-naive/src/views/demos/naive/index.vue b/apps/web-naive/src/views/demos/naive/index.vue index e328f4134..41d55109e 100644 --- a/apps/web-naive/src/views/demos/naive/index.vue +++ b/apps/web-naive/src/views/demos/naive/index.vue @@ -1,6 +1,7 @@ diff --git a/apps/web-naive/src/views/demos/table/index.vue b/apps/web-naive/src/views/demos/table/index.vue index 02acf5808..ddc958bc3 100644 --- a/apps/web-naive/src/views/demos/table/index.vue +++ b/apps/web-naive/src/views/demos/table/index.vue @@ -1,6 +1,8 @@ diff --git a/docs/.vitepress/config.mts b/docs/.vitepress/config.mts index 3e98f54db..78f9ed27b 100644 --- a/docs/.vitepress/config.mts +++ b/docs/.vitepress/config.mts @@ -162,7 +162,11 @@ function nav(): DefaultTheme.NavItem[] { items: [ { link: 'https://www.vben.pro', - text: 'Ant Design Vue 版本(默认)', + text: '演示版本', + }, + { + link: 'https://ant.vben.pro', + text: 'Ant Design Vue 版本', }, { link: 'https://naive.vben.pro', @@ -250,6 +254,7 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { text: '为什么选择我们?', }, { link: 'introduction/quick-start', text: '快速开始' }, + { link: 'introduction/thin', text: '精简版本' }, ], }, { @@ -284,6 +289,7 @@ function sidebarGuide(): DefaultTheme.SidebarItem[] { items: [ { link: 'project/standard', text: '规范' }, { link: 'project/cli', text: 'CLI' }, + { link: 'project/dir', text: '目录说明' }, { link: 'project/test', text: '单元测试' }, { link: 'project/tailwindcss', text: 'Tailwind CSS' }, { link: 'project/changeset', text: 'Changeset' }, diff --git a/docs/.vitepress/theme/components/vben-contributors.vue b/docs/.vitepress/theme/components/vben-contributors.vue index 987098b16..9b887d925 100644 --- a/docs/.vitepress/theme/components/vben-contributors.vue +++ b/docs/.vitepress/theme/components/vben-contributors.vue @@ -4,7 +4,10 @@

Contributors

- + Contributors
diff --git a/docs/src/guide/essentials/development.md b/docs/src/guide/essentials/development.md index 8fb82a195..4b92b10f1 100644 --- a/docs/src/guide/essentials/development.md +++ b/docs/src/guide/essentials/development.md @@ -78,6 +78,8 @@ npm 脚本是项目常见的配置,用于执行一些常见的任务,比如 "dev:docs": "pnpm -F @vben/docs run dev", // 启动web-ele应用 "dev:ele": "pnpm -F @vben/web-ele run dev", + // 启动演示应用 + "dev:play": "pnpm -F @vben/playground run dev", // 启动web-naive应用 "dev:naive": "pnpm -F @vben/web-naive run dev", // 格式化代码 diff --git a/docs/src/guide/essentials/server.md b/docs/src/guide/essentials/server.md index 5fe139678..26a839341 100644 --- a/docs/src/guide/essentials/server.md +++ b/docs/src/guide/essentials/server.md @@ -221,7 +221,7 @@ function createRequestClient(baseURL: string) { if (status >= 200 && status < 400 && code === 0) { return data; } - throw new Error(msg); + throw new Error(`Error ${status}: ${msg}`); }); return client; } diff --git a/docs/src/guide/in-depth/locale.md b/docs/src/guide/in-depth/locale.md index 69370e157..66626b7e2 100644 --- a/docs/src/guide/in-depth/locale.md +++ b/docs/src/guide/in-depth/locale.md @@ -198,7 +198,11 @@ async function loadDayjsLocale(lang: SupportedLanguagesType) { locale = await import('dayjs/locale/en'); } } - dayjs.locale(locale); + if (locale) { + dayjs.locale(locale); + } else { + console.error(`Failed to load dayjs locale for ${lang}`); + } } ``` diff --git a/docs/src/guide/introduction/quick-start.md b/docs/src/guide/introduction/quick-start.md index 47e86160a..852414f6a 100644 --- a/docs/src/guide/introduction/quick-start.md +++ b/docs/src/guide/introduction/quick-start.md @@ -72,11 +72,24 @@ pnpm install ### 运行项目 -执行以下命令即可运行项目: +执行以下命运行项目: ```bash # 启动项目 pnpm dev ``` +此时,你会看到类似如下的输出,选择你需要运行的项目: + +```bash +│ +◆ Select the app you need to run [dev]: +│ ● @vben/web-antd +│ ○ @vben/web-ele +│ ○ @vben/web-naive +│ ○ @vben/docs +│ ○ @vben/playground +└ +``` + 现在,你可以在浏览器访问 `http://localhost:5555` 查看项目。 diff --git a/docs/src/guide/introduction/thin.md b/docs/src/guide/introduction/thin.md new file mode 100644 index 000000000..818227e90 --- /dev/null +++ b/docs/src/guide/introduction/thin.md @@ -0,0 +1,62 @@ +# 精简版本 + +从 `5.0` 版本开始,我们不再提供精简的仓库或者分支。我们的目标是提供一个更加一致的开发体验,同时减少维护成本。在这里,我们将如何介绍自己的项目,如何去精简以及移除不需要的功能。 + +## 应用精简 + +首先,确认你需要的 `UI` 组件库版本,然后删除对应的应用,比如你选择使用 `Ant Design Vue`,那么你可以删除其他应用, 只需要删除下面两个文件夹即可: + +```bash +apps/web-ele +apps/web-native + +``` + +::: tip + +如果项目没有内置你需要的 `UI` 组件库应用,你可以直接全部删除其他应用。然后自行新建应用即可。 + +::: + +## 演示代码精简 + +如果你不需要演示代码,你可以直接删除的`playground`文件夹。 + +## 文档精简 + +如果你不需要文档,你可以直接删除`docs`文件夹。 + +## Mock 服务精简 + +如果你不需要`Mock`服务,你可以直接删除`apps/backend-mock`文件夹。同时在你的应用下`.env.development`文件中删除`VITE_NITRO_MOCK`变量。 + +```bash +# 是否开启 Nitro Mock服务,true 为开启,false 为关闭 +VITE_NITRO_MOCK=false +``` + +## 安装依赖 + +到这里,你已经完成了精简操作,接下来你可以安装依赖,并启动你的项目: + +```bash +# 根目录下执行 +pnpm install + +``` + +## 命令调整 + +在精简后,你可能需要根据你的项目调整命令,在根目录下的`package.json`文件中,你可以调整`scripts`字段,移除你不需要的命令。 + +```json +{ + "scripts": { + "dev:antd": "pnpm -F @vben/web-antd run dev", + "dev:docs": "pnpm -F @vben/docs run dev", + "dev:ele": "pnpm -F @vben/web-ele run dev", + "dev:play": "pnpm -F @vben/playground run dev", + "dev:naive": "pnpm -F @vben/web-naive run dev" + } +} +``` diff --git a/docs/src/guide/project/dir.md b/docs/src/guide/project/dir.md new file mode 100644 index 000000000..3b32fedaf --- /dev/null +++ b/docs/src/guide/project/dir.md @@ -0,0 +1,68 @@ +# 目录说明 + +目录使用 Monorepo 管理,项目结构如下: + +```bash +. +├── Dockerfile # Docker 镜像构建文件 +├── README.md # 项目说明文档 +├── apps # 项目应用目录 +│   ├── backend-mock # 后端模拟服务应用 +│   ├── web-antd # 基于 Ant Design Vue 的前端应用 +│   ├── web-ele # 基于 Element Plus 的前端应用 +│   └── web-naive # 基于 Naive UI 的前端应用 +├── build-local-docker-image.sh # 本地构建 Docker 镜像脚本 +├── cspell.json # CSpell 配置文件 +├── docs # 项目文档目录 +├── eslint.config.mjs # ESLint 配置文件 +├── internal # 内部工具目录 +│   ├── lint-configs # 代码检查配置 +│   │   ├── commitlint-config # Commitlint 配置 +│   │   ├── eslint-config # ESLint 配置 +│   │   ├── prettier-config # Prettier 配置 +│   │   └── stylelint-config # Stylelint 配置 +│   ├── node-utils # Node.js 工具 +│   ├── tailwind-config # Tailwind 配置 +│   ├── tsconfig # 通用 tsconfig 配置 +│   └── vite-config # 通用Vite 配置 +├── package.json # 项目依赖配置 +├── packages # 项目包目录 +│   ├── @core # 核心包 +│   │   ├── base # 基础包 +│   │   │   ├── design # 设计相关 +│   │   │   ├── icons # 图标 +│   │   │   ├── shared # 共享 +│   │   │   └── typings # 类型定义 +│   │   ├── composables # 组合式 API +│   │   ├── preferences # 偏好设置 +│   │   └── ui-kit # UI 组件集合 +│   │   ├── layout-ui # 布局 UI +│   │   ├── menu-ui # 菜单 UI +│   │   ├── shadcn-ui # shadcn UI +│   │   └── tabs-ui # 标签页 UI +│   ├── constants # 常量 +│   ├── effects # 副作用相关包 +│   │   ├── access # 访问控制 +│   │   ├── chart-ui # 图表 UI +│   │   ├── common-ui # 通用 UI +│   │   ├── hooks # 组合式 API +│   │   ├── layouts # 布局 +│   │   └── request # 请求 +│   ├── icons # 图标 +│   ├── locales # 国际化 +│   ├── preferences # 偏好设置 +│   ├── stores # 状态管理 +│   ├── styles # 样式 +│   ├── types # 类型定义 +│   └── utils # 工具 +├── playground # 演示目录 +├── pnpm-lock.yaml # pnpm 锁定文件 +├── pnpm-workspace.yaml # pnpm 工作区配置文件 +├── scripts # 脚本目录 +│   ├── turbo-run # Turbo 运行脚本 +│   └── vsh # VSH 脚本 +├── stylelint.config.mjs # Stylelint 配置文件 +├── turbo.json # Turbo 配置文件 +├── vben-admin.code-workspace # VS Code 工作区配置文件 +└── vitest.config.ts # Vite 配置文件 +``` diff --git a/internal/tsconfig/base.json b/internal/tsconfig/base.json index 82e35f319..1e45a7843 100644 --- a/internal/tsconfig/base.json +++ b/internal/tsconfig/base.json @@ -13,7 +13,6 @@ "moduleResolution": "node", "resolveJsonModule": true, - "allowImportingTsExtensions": true, "strict": true, "strictNullChecks": true, diff --git a/package.json b/package.json index 338e59a73..025bad215 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "dev:antd": "pnpm -F @vben/web-antd run dev", "dev:docs": "pnpm -F @vben/docs run dev", "dev:ele": "pnpm -F @vben/web-ele run dev", + "dev:play": "pnpm -F @vben/playground run dev", "dev:naive": "pnpm -F @vben/web-naive run dev", "format": "vsh lint --format", "lint": "vsh lint", @@ -69,6 +70,8 @@ "@vben/turbo-run": "workspace:*", "@vben/vite-config": "workspace:*", "@vben/vsh": "workspace:*", + "@vitejs/plugin-vue": "^5.1.2", + "@vitejs/plugin-vue-jsx": "^4.0.0", "@vue/test-utils": "^2.4.6", "autoprefixer": "^10.4.20", "cross-env": "^7.0.3", @@ -84,6 +87,7 @@ "unbuild": "^2.0.0", "vite": "^5.4.0", "vitest": "^2.0.5", + "vue": "^3.4.37", "vue-tsc": "^2.0.29" }, "engines": { diff --git a/packages/@core/base/design/src/css/global.css b/packages/@core/base/design/src/css/global.css index 6646403dd..562cafa93 100644 --- a/packages/@core/base/design/src/css/global.css +++ b/packages/@core/base/design/src/css/global.css @@ -35,7 +35,9 @@ min-height: 100vh; /* overflow: overlay; */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } a, diff --git a/packages/@core/base/design/src/design-tokens/default/index.css b/packages/@core/base/design/src/design-tokens/default/index.css index 5b0c985d1..bf3341751 100644 --- a/packages/@core/base/design/src/design-tokens/default/index.css +++ b/packages/@core/base/design/src/design-tokens/default/index.css @@ -8,7 +8,7 @@ /* 主体区域背景色 */ --background-deep: 210 11.11% 96.47%; - --foreground: 210 6% 21%; + --foreground: 222 84% 5%; /* Background color for */ --card: 0 0% 100%; diff --git a/packages/@core/base/shared/src/constants/vben.ts b/packages/@core/base/shared/src/constants/vben.ts index a72317579..4ae5d1e6a 100644 --- a/packages/@core/base/shared/src/constants/vben.ts +++ b/packages/@core/base/shared/src/constants/vben.ts @@ -22,3 +22,5 @@ export const VBEN_PREVIEW_URL = 'https://www.vben.pro'; export const VBEN_ELE_PREVIEW_URL = 'https://ele.vben.pro'; export const VBEN_NAIVE_PREVIEW_URL = 'https://naive.vben.pro'; + +export const VBEN_ANT_PREVIEW_URL = 'https://ant.vben.pro'; diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/alert-dialog/alert-dialog.vue b/packages/@core/ui-kit/shadcn-ui/src/components/alert-dialog/alert-dialog.vue index 833048830..3cc31f660 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/components/alert-dialog/alert-dialog.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/components/alert-dialog/alert-dialog.vue @@ -8,7 +8,7 @@ import { AlertDialogHeader, AlertDialog as AlertDialogRoot, AlertDialogTitle, -} from '@vben-core/shadcn-ui/components/ui/alert-dialog'; +} from '../ui/alert-dialog'; interface Props { cancelText?: string; diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue b/packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue index 1e535f6fe..e42326db2 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/components/avatar/avatar.vue @@ -5,20 +5,15 @@ import type { AvatarRootProps, } from 'radix-vue'; -import type { HTMLAttributes } from 'vue'; import { computed } from 'vue'; -import { - Avatar, - AvatarFallback, - AvatarImage, -} from '@vben-core/shadcn-ui/components/ui/avatar'; +import { Avatar, AvatarFallback, AvatarImage } from '../ui/avatar'; interface Props extends AvatarRootProps, AvatarFallbackProps, AvatarImageProps { alt?: string; - class?: HTMLAttributes['class']; + class?: any; dot?: boolean; - dotClass?: HTMLAttributes['class']; + dotClass?: any; } defineOptions({ diff --git a/packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-background.vue b/packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-background.vue index f27ab442c..7ba685a8c 100644 --- a/packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-background.vue +++ b/packages/@core/ui-kit/shadcn-ui/src/components/breadcrumb/breadcrumb-background.vue @@ -1,5 +1,5 @@