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
## 貢献者
-
+
## 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
-
+
## 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
+
+
+
+
+
## 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 @@
+
+
+
+
文本省略示例
-
住在我心里孤独的
孤独的海怪 痛苦之王
开始厌倦
- 深海的光 停滞的海浪
- Element Plus组件使用演示
- naive组件使用演示
-
Contributors
-Default Slot Content
', + }, + }); + + expect(wrapper.html()).toContain('Default Slot Content
'); + }); + + it('renders footer slot when showFooter is true', () => { + const wrapper = mount(Page, { + props: { + showFooter: true, + }, + slots: { + footer: 'Footer Slot Content
', + }, + }); + + expect(wrapper.html()).toContain('Footer Slot Content
'); + }); + + it('applies the custom contentClass', () => { + const wrapper = mount(Page, { + props: { + contentClass: 'custom-class', + }, + }); + + const contentDiv = wrapper.find('.m-4'); + expect(contentDiv.classes()).toContain('custom-class'); + }); + + it('does not render description slot if description prop is provided', () => { + const wrapper = mount(Page, { + props: { + description: 'Test Description', + }, + slots: { + description: 'Description Slot Content
', + }, + }); + + expect(wrapper.text()).toContain('Test Description'); + expect(wrapper.html()).not.toContain('Description Slot Content'); + }); +}); diff --git a/packages/effects/common-ui/src/components/page/index.ts b/packages/effects/common-ui/src/components/page/index.ts new file mode 100644 index 000000000..65bf3c697 --- /dev/null +++ b/packages/effects/common-ui/src/components/page/index.ts @@ -0,0 +1 @@ +export { default as Page } from './page.vue'; diff --git a/packages/effects/common-ui/src/components/page/page.vue b/packages/effects/common-ui/src/components/page/page.vue new file mode 100644 index 000000000..cdbefa230 --- /dev/null +++ b/packages/effects/common-ui/src/components/page/page.vue @@ -0,0 +1,45 @@ + + + +
+
-