Files
xk-admin/apps/web-antd/src/router/guard.ts
李琦 82b10bd122 Merge remote-tracking branch 'vben/main' into vben-dev
# Conflicts:
#	.gitignore
#	.husky/pre-commit
#	.vscode/extensions.json
#	.vscode/settings.json
#	README.ja-JP.md
#	README.md
#	README.zh-CN.md
#	apps/backend-mock/api/auth/codes.ts
#	apps/backend-mock/api/auth/login.post.ts
#	apps/backend-mock/api/auth/logout.post.ts
#	apps/backend-mock/api/auth/refresh.post.ts
#	apps/backend-mock/api/menu/all.ts
#	apps/backend-mock/api/status.ts
#	apps/backend-mock/api/table/list.ts
#	apps/backend-mock/api/test.get.ts
#	apps/backend-mock/api/test.post.ts
#	apps/backend-mock/api/user/info.ts
#	apps/backend-mock/middleware/1.api.ts
#	apps/backend-mock/nitro.config.ts
#	apps/backend-mock/package.json
#	apps/backend-mock/routes/[...].ts
#	apps/backend-mock/tsconfig.json
#	apps/backend-mock/utils/cookie-utils.ts
#	apps/backend-mock/utils/jwt-utils.ts
#	apps/backend-mock/utils/mock-data.ts
#	apps/backend-mock/utils/response.ts
#	apps/web-antd/.env
#	apps/web-antd/src/adapter/component/index.ts
#	apps/web-antd/src/adapter/form.ts
#	apps/web-antd/src/api/request.ts
#	apps/web-antd/src/layouts/auth.vue
#	apps/web-antd/src/layouts/basic.vue
#	apps/web-antd/src/preferences.ts
#	apps/web-antd/src/router/guard.ts
#	apps/web-antd/src/router/routes/modules/demos.ts
#	apps/web-antd/src/store/auth.ts
#	apps/web-antd/src/views/demos/antd/index.vue
#	apps/web-antdv-next/vite.config.ts
#	apps/web-ele/.env
#	apps/web-ele/index.html
#	apps/web-ele/package.json
#	apps/web-ele/src/adapter/component/index.ts
#	apps/web-ele/src/adapter/form.ts
#	apps/web-ele/src/adapter/vxe-table.ts
#	apps/web-ele/src/api/request.ts
#	apps/web-ele/src/bootstrap.ts
#	apps/web-ele/src/layouts/auth.vue
#	apps/web-ele/src/layouts/basic.vue
#	apps/web-ele/src/locales/index.ts
#	apps/web-ele/src/locales/langs/en-US/demos.json
#	apps/web-ele/src/locales/langs/en-US/page.json
#	apps/web-ele/src/locales/langs/zh-CN/demos.json
#	apps/web-ele/src/locales/langs/zh-CN/page.json
#	apps/web-ele/src/preferences.ts
#	apps/web-ele/src/router/guard.ts
#	apps/web-ele/src/router/routes/core.ts
#	apps/web-ele/src/router/routes/modules/dashboard.ts
#	apps/web-ele/src/router/routes/modules/demos.ts
#	apps/web-ele/src/router/routes/modules/vben.ts
#	apps/web-ele/src/store/auth.ts
#	apps/web-ele/src/views/_core/authentication/code-login.vue
#	apps/web-ele/src/views/_core/authentication/forget-password.vue
#	apps/web-ele/src/views/_core/authentication/register.vue
#	apps/web-ele/src/views/dashboard/analytics/analytics-trends.vue
#	apps/web-ele/src/views/dashboard/analytics/analytics-visits-data.vue
#	apps/web-ele/src/views/dashboard/analytics/analytics-visits-sales.vue
#	apps/web-ele/src/views/dashboard/analytics/analytics-visits-source.vue
#	apps/web-ele/src/views/dashboard/analytics/analytics-visits.vue
#	apps/web-ele/src/views/dashboard/analytics/index.vue
#	apps/web-ele/src/views/demos/element/index.vue
#	apps/web-ele/src/views/demos/form/basic.vue
#	apps/web-ele/tsconfig.json
#	apps/web-ele/tsconfig.node.json
#	apps/web-naive/.env
#	apps/web-naive/index.html
#	apps/web-naive/package.json
#	apps/web-naive/src/adapter/component/index.ts
#	apps/web-naive/src/adapter/form.ts
#	apps/web-naive/src/adapter/vxe-table.ts
#	apps/web-naive/src/api/request.ts
#	apps/web-naive/src/bootstrap.ts
#	apps/web-naive/src/layouts/auth.vue
#	apps/web-naive/src/layouts/basic.vue
#	apps/web-naive/src/locales/index.ts
#	apps/web-naive/src/locales/langs/en-US/demos.json
#	apps/web-naive/src/locales/langs/en-US/page.json
#	apps/web-naive/src/locales/langs/zh-CN/demos.json
#	apps/web-naive/src/locales/langs/zh-CN/page.json
#	apps/web-naive/src/preferences.ts
#	apps/web-naive/src/router/guard.ts
#	apps/web-naive/src/router/routes/core.ts
#	apps/web-naive/src/router/routes/modules/dashboard.ts
#	apps/web-naive/src/router/routes/modules/demos.ts
#	apps/web-naive/src/router/routes/modules/vben.ts
#	apps/web-naive/src/store/auth.ts
#	apps/web-naive/src/views/_core/authentication/code-login.vue
#	apps/web-naive/src/views/_core/authentication/forget-password.vue
#	apps/web-naive/src/views/_core/authentication/register.vue
#	apps/web-naive/src/views/dashboard/analytics/analytics-trends.vue
#	apps/web-naive/src/views/dashboard/analytics/analytics-visits-data.vue
#	apps/web-naive/src/views/dashboard/analytics/analytics-visits-sales.vue
#	apps/web-naive/src/views/dashboard/analytics/analytics-visits-source.vue
#	apps/web-naive/src/views/dashboard/analytics/analytics-visits.vue
#	apps/web-naive/src/views/dashboard/analytics/index.vue
#	apps/web-naive/src/views/demos/form/basic.vue
#	apps/web-naive/src/views/demos/naive/index.vue
#	apps/web-naive/tsconfig.json
#	apps/web-naive/tsconfig.node.json
#	apps/web-naive/vite.config.ts
#	docs/.vitepress/components/demo-preview.vue
#	docs/.vitepress/components/preview-group.vue
#	docs/.vitepress/config/en.mts
#	docs/.vitepress/config/index.mts
#	docs/.vitepress/config/plugins/demo-preview.ts
#	docs/.vitepress/config/shared.mts
#	docs/.vitepress/config/zh.mts
#	docs/.vitepress/theme/components/site-layout.vue
#	docs/.vitepress/theme/components/vben-contributors.vue
#	docs/.vitepress/theme/styles/variables.css
#	docs/package.json
#	docs/src/_env/adapter/component.ts
#	docs/src/_env/adapter/form.ts
#	docs/src/_env/adapter/vxe-table.ts
#	docs/src/commercial/community.md
#	docs/src/components/common-ui/vben-count-to-animator.md
#	docs/src/components/common-ui/vben-drawer.md
#	docs/src/components/common-ui/vben-form.md
#	docs/src/components/common-ui/vben-modal.md
#	docs/src/components/common-ui/vben-vxe-table.md
#	docs/src/components/layout-ui/page.md
#	docs/src/demos/vben-drawer/auto-height/drawer.vue
#	docs/src/demos/vben-drawer/basic/index.vue
#	docs/src/demos/vben-drawer/dynamic/index.vue
#	docs/src/demos/vben-drawer/shared-data/drawer.vue
#	docs/src/demos/vben-drawer/shared-data/index.vue
#	docs/src/demos/vben-form/api/index.vue
#	docs/src/demos/vben-form/basic/index.vue
#	docs/src/demos/vben-form/custom/index.vue
#	docs/src/demos/vben-form/dynamic/index.vue
#	docs/src/demos/vben-form/query/index.vue
#	docs/src/demos/vben-form/rules/index.vue
#	docs/src/demos/vben-modal/auto-height/modal.vue
#	docs/src/demos/vben-modal/basic/index.vue
#	docs/src/demos/vben-modal/dynamic/index.vue
#	docs/src/demos/vben-modal/shared-data/index.vue
#	docs/src/demos/vben-modal/shared-data/modal.vue
#	docs/src/demos/vben-vxe-table/basic/index.vue
#	docs/src/demos/vben-vxe-table/custom-cell/index.vue
#	docs/src/demos/vben-vxe-table/edit-row/index.vue
#	docs/src/demos/vben-vxe-table/fixed/index.vue
#	docs/src/demos/vben-vxe-table/form/index.vue
#	docs/src/demos/vben-vxe-table/remote/index.vue
#	docs/src/demos/vben-vxe-table/tree/index.vue
#	docs/src/demos/vben-vxe-table/virtual/index.vue
#	docs/src/en/guide/essentials/development.md
#	docs/src/en/guide/essentials/external-module.md
#	docs/src/en/guide/essentials/route.md
#	docs/src/en/guide/essentials/server.md
#	docs/src/en/guide/essentials/settings.md
#	docs/src/en/guide/in-depth/access.md
#	docs/src/en/guide/in-depth/loading.md
#	docs/src/en/guide/in-depth/locale.md
#	docs/src/en/guide/in-depth/theme.md
#	docs/src/en/guide/introduction/quick-start.md
#	docs/src/en/guide/introduction/thin.md
#	docs/src/en/guide/introduction/vben.md
#	docs/src/en/guide/other/faq.md
#	docs/src/en/guide/project/dir.md
#	docs/src/en/guide/project/standard.md
#	docs/src/en/guide/project/tailwindcss.md
#	docs/src/en/index.md
#	docs/src/friend-links/index.md
#	docs/src/guide/essentials/build.md
#	docs/src/guide/essentials/development.md
#	docs/src/guide/essentials/external-module.md
#	docs/src/guide/essentials/route.md
#	docs/src/guide/essentials/server.md
#	docs/src/guide/essentials/settings.md
#	docs/src/guide/in-depth/access.md
#	docs/src/guide/in-depth/check-updates.md
#	docs/src/guide/in-depth/loading.md
#	docs/src/guide/in-depth/locale.md
#	docs/src/guide/in-depth/theme.md
#	docs/src/guide/introduction/quick-start.md
#	docs/src/guide/introduction/thin.md
#	docs/src/guide/introduction/vben.md
#	docs/src/guide/introduction/why.md
#	docs/src/guide/other/faq.md
#	docs/src/guide/project/dir.md
#	docs/src/guide/project/standard.md
#	docs/src/guide/project/tailwindcss.md
#	docs/src/index.md
#	docs/tsconfig.json
#	package.json
#	packages/@core/ui-kit/shadcn-ui/src/components/logo/logo.vue
#	packages/constants/src/core.ts
#	packages/effects/common-ui/src/components/index.ts
#	packages/effects/common-ui/src/ui/dashboard/analysis/analysis-overview.vue
#	packages/effects/common-ui/src/ui/dashboard/workbench/workbench-header.vue
#	packages/effects/common-ui/src/ui/dashboard/workbench/workbench-project.vue
#	packages/effects/layouts/src/authentication/authentication.vue
#	packages/effects/layouts/src/basic/layout.vue
#	packages/effects/layouts/src/widgets/notification/notification.vue
#	packages/effects/layouts/src/widgets/notification/types.ts
#	packages/icons/src/iconify/index.ts
#	packages/icons/src/svg/index.ts
#	packages/stores/src/modules/user.ts
#	playground/src/adapter/component/index.ts
#	playground/src/store/auth.ts
#	pnpm-lock.yaml
#	vben-admin.code-workspace
2026-08-10 16:55:17 +08:00

134 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Router } from 'vue-router';
import { DEFAULT_HOME_PATH, LOGIN_PATH } from '@vben/constants';
import { preferences } from '@vben/preferences';
import { useAccessStore, useUserStore } from '@vben/stores';
import { startProgress, stopProgress } from '@vben/utils';
import { accessRoutes, coreRouteNames } from '#/router/routes';
import { useAuthStore } from '#/store';
import { generateAccess } from './access';
/**
* 通用守卫配置
* @param router
*/
function setupCommonGuard(router: Router) {
// 记录已经加载的页面
const loadedPaths = new Set<string>();
router.beforeEach((to) => {
to.meta.loaded = loadedPaths.has(to.path);
// 页面加载进度条
if (!to.meta.loaded && preferences.transition.progress) {
startProgress();
}
return true;
});
router.afterEach((to) => {
// 记录页面是否加载,如果已经加载,后续的页面切换动画等效果不在重复执行
loadedPaths.add(to.path);
// 关闭页面加载进度条
if (preferences.transition.progress) {
stopProgress();
}
});
}
/**
* 权限访问守卫配置
* @param router
*/
function setupAccessGuard(router: Router) {
router.beforeEach(async (to, from) => {
const accessStore = useAccessStore();
const userStore = useUserStore();
const authStore = useAuthStore();
// 基本路由,这些路由不需要进入权限拦截
if (coreRouteNames.includes(to.name as string)) {
if (to.path === LOGIN_PATH && accessStore.accessToken) {
return decodeURIComponent(
(to.query?.redirect as string) ||
userStore.userInfo?.homePath ||
DEFAULT_HOME_PATH,
);
}
return true;
}
// accessToken 检查
if (!accessStore.accessToken) {
// 明确声明忽略权限访问权限,则可以访问
if (to.meta.ignoreAccess) {
return true;
}
// 没有访问权限,跳转登录页面
if (to.fullPath !== LOGIN_PATH) {
return {
path: LOGIN_PATH,
// 如不需要,直接删除 query
query:
to.fullPath === DEFAULT_HOME_PATH
? {}
: { redirect: encodeURIComponent(to.fullPath) },
// 携带当前跳转的页面,登录后重新跳转该页面
replace: true,
};
}
return to;
}
// 是否已经生成过动态路由
if (accessStore.isAccessChecked) {
return true;
}
// 生成路由表
// 当前登录用户拥有的角色标识列表
const userInfo = userStore.userInfo || (await authStore.fetchUserInfo());
const userRoles = userInfo?.roles ?? [];
// 生成菜单和路由
const { accessibleMenus, accessibleRoutes } = await generateAccess({
roles: userRoles,
router,
// 则会在菜单中显示但是访问会被重定向到403
routes: accessRoutes,
});
// 保存菜单信息和路由信息
accessStore.setAccessMenus(accessibleMenus);
accessStore.setAccessRoutes(accessibleRoutes);
accessStore.setIsAccessChecked(true);
const redirectPath = (from.query.redirect ??
(to.path === DEFAULT_HOME_PATH
? userInfo.home_path || DEFAULT_HOME_PATH
: to.fullPath)) as string;
return {
...router.resolve(decodeURIComponent(redirectPath)),
replace: true,
};
});
}
/**
* 项目守卫配置
* @param router
*/
function createRouterGuard(router: Router) {
/** 通用 */
setupCommonGuard(router);
/** 权限访问 */
setupAccessGuard(router);
}
export { createRouterGuard };