🔱: [client] sync upgrade with 7 commits [trident-sync]

chore:
Merge branch 'vben'

# Conflicts:
#	package.json
perf: antdv示例改成使用vben框架
chore: vben
chore: vben
chore: vben
This commit is contained in:
GitHub Actions Bot
2025-03-03 19:24:51 +00:00
parent de26ee9383
commit 335d175d57
649 changed files with 36984 additions and 826 deletions
@@ -0,0 +1,35 @@
import type { ComponentRecordType, GenerateMenuAndRoutesOptions } from "/@/vben/types";
import { generateAccessible } from "/@/vben/access";
import { preferences } from "/@/vben/preferences";
import { BasicLayout, IFrameView } from "/@/vben/layouts";
const forbiddenComponent = () => import("#/views/_core/fallback/forbidden.vue");
async function generateAccess(options: GenerateMenuAndRoutesOptions) {
const pageMap: ComponentRecordType = import.meta.glob("../views/**/*.vue");
const layoutMap: ComponentRecordType = {
BasicLayout,
IFrameView
} as any;
return await generateAccessible(preferences.app.accessMode, {
...options,
// fetchMenuListAsync: async () => {
// message.loading({
// content: `${$t("common.loadingMenu")}...`,
// duration: 1.5
// });
// return await getAllMenusApi();
// },
// 可以指定没有权限跳转403页面
forbiddenComponent,
// 如果 route.meta.menuVisibleWithForbidden = true
layoutMap,
pageMap
});
}
export { generateAccess };
@@ -0,0 +1,109 @@
import type { Router } from "vue-router";
import { DEFAULT_HOME_PATH, LOGIN_PATH } from "/@/vben/constants";
import { preferences } from "/@/vben/preferences";
import { useAccessStore } from "/@/vben/stores";
import { generateMenus, startProgress, stopProgress } from "/@/vben/utils";
import { useUserStore } from "/@/store/modules/user";
import { frameworkRoutes } from "/@/router/resolve";
/**
* 通用守卫配置
* @param router
*/
export function setupCommonGuard(router: Router) {
// 记录已经加载的页面
const loadedPaths = new Set<string>();
router.beforeEach(async (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 needAuth = to.matched.some((r) => {
return r.meta?.auth || r.meta?.permission;
});
const accessStore = useAccessStore();
if (needAuth) {
if (!accessStore.accessToken) {
// 没有访问权限,跳转登录页面
if (to.fullPath !== LOGIN_PATH) {
return {
path: LOGIN_PATH,
// 如不需要,直接删除 query
query: to.fullPath === DEFAULT_HOME_PATH ? {} : { redirect: encodeURIComponent(to.fullPath) },
// 携带当前跳转的页面,登录后重新跳转该页面
replace: true
};
}
return true;
}
}
// 是否已经生成过动态路由
if (!accessStore.isAccessChecked) {
const accessibleMenus = await generateMenus(frameworkRoutes[0].children, router);
accessStore.setAccessRoutes(frameworkRoutes);
accessStore.setAccessMenus(accessibleMenus);
accessStore.setIsAccessChecked(true);
}
// 生成菜单和路由
// const { accessibleMenus, accessibleRoutes } = await generateAccess({
// roles: [],
// router,
// // 则会在菜单中显示,但是访问会被重定向到403
// routes: accessRoutes
// });
//
// // 保存菜单信息和路由信息
// accessStore.setAccessMenus(accessibleMenus);
// accessStore.setAccessRoutes(accessibleRoutes);
// const redirectPath = (from.query.redirect ?? (to.path === DEFAULT_HOME_PATH ? DEFAULT_HOME_PATH : to.fullPath)) as string;
//
// return {
// ...router.resolve(decodeURIComponent(redirectPath)),
// replace: true
// };
return true;
});
}
/**
* 项目守卫配置
* @param router
*/
function createRouterGuard(router: Router) {
/** 通用 */
setupCommonGuard(router);
/** 权限访问 */
setupAccessGuard(router);
}
export { createRouterGuard };
+63 -64
View File
@@ -1,74 +1,73 @@
import { createRouter, createWebHashHistory } from "vue-router";
// 进度条
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { usePageStore } from "../store/modules/page";
import { site } from "../utils/util.site";
import { routes } from "./resolve";
import { useResourceStore } from "../store/modules/resource";
import { useUserStore } from "../store/modules/user";
import { createRouterGuard } from "/@/router/guard";
const router = createRouter({
history: createWebHashHistory(),
routes
});
//
// /**
// * 路由拦截
// */
// router.beforeEach(async (to, from, next) => {
// // 进度条
// NProgress.start();
// // 修复三级以上路由页面无法缓存的问题
// if (to.matched && to.matched.length > 2) {
// to.matched.splice(1, to.matched.length - 2);
// }
// // 验证当前路由所有的匹配中是否需要有登录验证的
// if (
// to.matched.some((r) => {
// return r.meta?.auth || r.meta?.permission;
// })
// ) {
// const userStore = useUserStore();
// // 这里暂时将cookie里是否存有token作为验证是否登录的条件
// // 请根据自身业务需要修改
// const token = userStore.getToken;
// if (token) {
// next();
// } else {
// // 没有登录的时候跳转到登录界面
// // 携带上登陆成功之后需要跳转的页面完整路径
// next({
// name: "login",
// query: {
// redirect: to.fullPath
// }
// });
// // https://github.com/d2-projects/d2-admin/issues/138
// NProgress.done();
// }
// } else {
// // 不需要身份校验 直接通过
// next();
// }
// });
//
// router.afterEach((to: any) => {
// // 进度条
// NProgress.done();
// // 多页控制 打开新的页面
// const pageStore = usePageStore();
// // for (const item of to.matched) {
// // pageStore.keepAlivePush(item.name);
// // }
// pageStore.open(to);
// // 更改标题
// site.title(to.meta.title);
//
// //修改左侧边栏
// const matched = to.matched;
// if (matched.length > 0) {
// const resourceStore = useResourceStore();
// resourceStore.setAsideMenuByCurrentRoute(matched);
// }
// });
/**
* 路由拦截
*/
router.beforeEach(async (to, from, next) => {
// 进度条
NProgress.start();
// 修复三级以上路由页面无法缓存的问题
if (to.matched && to.matched.length > 2) {
to.matched.splice(1, to.matched.length - 2);
}
// 验证当前路由所有的匹配中是否需要有登录验证的
if (
to.matched.some((r) => {
return r.meta?.auth || r.meta?.permission;
})
) {
const userStore = useUserStore();
// 这里暂时将cookie里是否存有token作为验证是否登录的条件
// 请根据自身业务需要修改
const token = userStore.getToken;
if (token) {
next();
} else {
// 没有登录的时候跳转到登录界面
// 携带上登陆成功之后需要跳转的页面完整路径
next({
name: "login",
query: {
redirect: to.fullPath
}
});
// https://github.com/d2-projects/d2-admin/issues/138
NProgress.done();
}
} else {
// 不需要身份校验 直接通过
next();
}
});
router.afterEach((to: any) => {
// 进度条
NProgress.done();
// 多页控制 打开新的页面
const pageStore = usePageStore();
// for (const item of to.matched) {
// pageStore.keepAlivePush(item.name);
// }
pageStore.open(to);
// 更改标题
site.title(to.meta.title);
//修改左侧边栏
const matched = to.matched;
if (matched.length > 0) {
const resourceStore = useResourceStore();
resourceStore.setAsideMenuByCurrentRoute(matched);
}
});
createRouterGuard(router);
export default router;
@@ -152,4 +152,3 @@ const routes = [...outsideRoutes, ...frameworkRoutes];
const frameworkMenus = frameworkRet.menus;
const headerMenus = headerRet.menus;
export { routes, outsideRoutes, frameworkRoutes, frameworkMenus, headerMenus, findMenus, filterMenus };
@@ -1,17 +1,26 @@
import LayoutFramework from "/src/layout/layout-framework.vue";
import { crudResources } from "/@/router/source/modules/crud";
// import { uiResources } from "/@/router/source/modules/ui";
// import { integrationResources } from "/@/router/source/modules/integration";
import { sysResources } from "/@/router/source/modules/sys";
import LayoutBasic from "/@/layout/layout-basic.vue";
import type { RouteRecordRaw } from "vue-router";
import { mergeRouteModules } from "/@/vben/utils";
const dynamicRouteFiles = import.meta.glob("./modules/**/*.ts", {
eager: true
});
/** 动态路由 */
const dynamicRoutes: RouteRecordRaw[] = mergeRouteModules(dynamicRouteFiles);
export const frameworkResource = [
{
title: "框架",
name: "framework",
name: "root",
path: "/",
redirect: "/index",
component: LayoutFramework,
component: LayoutBasic,
meta: {
icon: "ion:accessibility"
icon: "ion:accessibility",
hideInBreadcrumb: true
},
children: [
{
@@ -22,12 +31,11 @@ export const frameworkResource = [
meta: {
fixedAside: true,
showOnHeader: false,
icon: "ion:home-outline"
icon: "ion:home-outline",
auth: true
}
},
...crudResources,
// ...integrationResources,
...sysResources
...dynamicRoutes
]
}
];
@@ -15,6 +15,7 @@ export const crudResources = [
component: "/crud/debug/index.vue",
meta: {
isMenu: false
// hideInMenu: true
}
},
{
@@ -794,3 +795,5 @@ export const crudResources = [
]
}
];
export default crudResources;
@@ -1,3 +1,6 @@
import type { RouteRecordRaw } from "vue-router";
import BasicLayout from "/@/vben/layouts/basic/layout.vue";
export const integrationResources = [
{
title: "集成",
@@ -20,3 +23,5 @@ export const integrationResources = [
]
}
];
// export default integrationResources;
@@ -1,4 +1,5 @@
import LayoutPass from "/@/layout/layout-pass.vue";
import BasicLayout from "/@/vben/layouts/basic/layout.vue";
export const sysResources = [
{
@@ -6,7 +7,6 @@ export const sysResources = [
name: "sys",
path: "/sys",
redirect: "/sys/authority",
component: LayoutPass,
meta: {
icon: "ion:settings-outline",
permission: "sys"
@@ -59,3 +59,5 @@ export const sysResources = [
]
}
];
export default sysResources;
@@ -1,3 +1,5 @@
import BasicLayout from "/@/vben/layouts/basic/layout.vue";
export const uiResources = [
{
title: "UI示例",
@@ -28,3 +30,5 @@ export const uiResources = [
]
}
];
export default uiResources;