diff --git a/.github/contributing.md b/.github/contributing.md
index 9a5211b2..f22370f3 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 6fef16be..fd88affe 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 9832a900..08ff80b7 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 a0fec000..cf48052d 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 08bd54f0..3b4e323c 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 eb3f43d5..38a9c5e2 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 4b76d886..61076b6d 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 f794c792..700f8357 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 5ce954bc..7cf502ed 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 9137ef6e..73e8fbeb 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 87821d87..c14a467f 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 c27e90c4..25e2e2fc 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 2b42e898..4b0e0413 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 a3e23661..1751f4e5 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 13179fd2..864c721f 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 86fbcabc..31d3475b 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 1581d015..f6b79f06 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 ad88a548..fa28acc7 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 3a0daabe..48e38fb2 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 1bef4d4e..261c847c 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 4dfc163f..8230f6e5 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 00000000..8286bebb
--- /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 00000000..65bf3c69 --- /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 00000000..cdbefa23 --- /dev/null +++ b/packages/effects/common-ui/src/components/page/page.vue @@ -0,0 +1,45 @@ + + + +
+
-