feat: init naive base
This commit is contained in:
@@ -1,20 +1,21 @@
|
||||
import type {
|
||||
AppRouteRecordRaw,
|
||||
ComponentRecordType,
|
||||
GenerateMenuAndRoutesOptions,
|
||||
} from '@vben/types';
|
||||
|
||||
import { generateAccessible } from '@vben/access';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useAccessStore } from '@vben/stores';
|
||||
import { convertServerMenuToRouteRecordStringComponent } from '@vben/utils';
|
||||
|
||||
import { message } from '#/adapter/naive';
|
||||
import { getAllMenusApi } from '#/api';
|
||||
import { BasicLayout, IFrameView } from '#/layouts';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
const forbiddenComponent = () => import('#/views/_core/fallback/forbidden.vue');
|
||||
|
||||
async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
||||
const pageMap: ComponentRecordType = import.meta.glob('../views/**/*.vue');
|
||||
const accessStore = useAccessStore();
|
||||
|
||||
const layoutMap: ComponentRecordType = {
|
||||
BasicLayout,
|
||||
@@ -24,10 +25,10 @@ async function generateAccess(options: GenerateMenuAndRoutesOptions) {
|
||||
return await generateAccessible(preferences.app.accessMode, {
|
||||
...options,
|
||||
fetchMenuListAsync: async () => {
|
||||
message.loading(`${$t('common.loadingMenu')}...`, {
|
||||
duration: 1.5,
|
||||
});
|
||||
return await getAllMenusApi();
|
||||
// 由于 yudao 通过 accessStore 读取,所以不在进行 message.loading 提示
|
||||
// 补充说明:accessStore.accessMenus 一开始是 AppRouteRecordRaw 类型(后端加载),后面被赋值成 MenuRecordRaw 类型(前端转换)
|
||||
const accessMenus = accessStore.accessMenus as AppRouteRecordRaw[];
|
||||
return convertServerMenuToRouteRecordStringComponent(accessMenus);
|
||||
},
|
||||
// 可以指定没有权限跳转403页面
|
||||
forbiddenComponent,
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { $t } from '@vben/locales';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useAccessStore, useUserStore } from '@vben/stores';
|
||||
import { useAccessStore, useDictStore, useUserStore } from '@vben/stores';
|
||||
import { startProgress, stopProgress } from '@vben/utils';
|
||||
|
||||
import { message } from '#/adapter/naive';
|
||||
import { getSimpleDictDataList } from '#/api/system/dict/data';
|
||||
import { accessRoutes, coreRouteNames } from '#/router/routes';
|
||||
import { useAuthStore } from '#/store';
|
||||
|
||||
@@ -49,6 +52,7 @@ function setupAccessGuard(router: Router) {
|
||||
const accessStore = useAccessStore();
|
||||
const userStore = useUserStore();
|
||||
const authStore = useAuthStore();
|
||||
const dictStore = useDictStore();
|
||||
|
||||
// 基本路由,这些路由不需要进入权限拦截
|
||||
if (coreRouteNames.includes(to.name as string)) {
|
||||
@@ -89,10 +93,26 @@ function setupAccessGuard(router: Router) {
|
||||
if (accessStore.isAccessChecked) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 加载字典数据(不阻塞加载)
|
||||
dictStore.setDictCacheByApi(getSimpleDictDataList);
|
||||
|
||||
// 生成路由表
|
||||
// 当前登录用户拥有的角色标识列表
|
||||
const userInfo = userStore.userInfo || (await authStore.fetchUserInfo());
|
||||
const userRoles = userInfo.roles ?? [];
|
||||
let userInfo = userStore.userInfo;
|
||||
if (!userInfo) {
|
||||
// add by 芋艿:由于 yudao 是 fetchUserInfo 统一加载用户 + 权限信息,所以将 fetchMenuListAsync
|
||||
const loading = message.loading(`${$t('common.loadingMenu')}...`);
|
||||
try {
|
||||
const authPermissionInfo = await authStore.fetchUserInfo();
|
||||
if (authPermissionInfo) {
|
||||
userInfo = authPermissionInfo.user;
|
||||
}
|
||||
} finally {
|
||||
loading.destroy();
|
||||
}
|
||||
}
|
||||
const userRoles = userStore.userRoles ?? [];
|
||||
|
||||
// 生成菜单和路由
|
||||
const { accessibleMenus, accessibleRoutes } = await generateAccess({
|
||||
@@ -106,9 +126,10 @@ function setupAccessGuard(router: Router) {
|
||||
accessStore.setAccessMenus(accessibleMenus);
|
||||
accessStore.setAccessRoutes(accessibleRoutes);
|
||||
accessStore.setIsAccessChecked(true);
|
||||
userStore.setUserRoles(userRoles);
|
||||
const redirectPath = (from.query.redirect ??
|
||||
(to.path === preferences.app.defaultHomePath
|
||||
? userInfo.homePath || preferences.app.defaultHomePath
|
||||
? userInfo?.homePath || preferences.app.defaultHomePath
|
||||
: to.fullPath)) as string;
|
||||
|
||||
return {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { resetStaticRoutes } from '@vben/utils';
|
||||
|
||||
import { createRouterGuard } from './guard';
|
||||
import { routes } from './routes';
|
||||
import { setupBaiduTongJi } from './tongji';
|
||||
|
||||
/**
|
||||
* @zh_CN 创建vue-router实例
|
||||
@@ -33,5 +34,7 @@ const resetRoutes = () => resetStaticRoutes(router, routes);
|
||||
|
||||
// 创建路由守卫
|
||||
createRouterGuard(router);
|
||||
// 设置百度统计
|
||||
setupBaiduTongJi(router);
|
||||
|
||||
export { resetRoutes, router };
|
||||
|
||||
@@ -90,6 +90,23 @@ const coreRoutes: RouteRecordRaw[] = [
|
||||
title: $t('page.auth.register'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'SocialLogin',
|
||||
path: 'social-login',
|
||||
component: () =>
|
||||
import('#/views/_core/authentication/social-login.vue'),
|
||||
meta: {
|
||||
title: $t('page.auth.login'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'SSOLogin',
|
||||
path: 'sso-login',
|
||||
component: () => import('#/views/_core/authentication/sso-login.vue'),
|
||||
meta: {
|
||||
title: $t('page.auth.login'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -34,4 +34,14 @@ const coreRouteNames = traverseTreeValues(coreRoutes, (route) => route.name);
|
||||
|
||||
/** 有权限校验的路由列表,包含动态路由和静态路由 */
|
||||
const accessRoutes = [...dynamicRoutes, ...staticRoutes];
|
||||
export { accessRoutes, coreRouteNames, routes };
|
||||
|
||||
// add by 芋艿:from https://github.com/vbenjs/vue-vben-admin/blob/main/playground/src/router/routes/index.ts#L38-L45
|
||||
const componentKeys: string[] = Object.keys(
|
||||
import.meta.glob('../../views/**/*.vue'),
|
||||
)
|
||||
.filter((item) => !item.includes('/modules/'))
|
||||
.map((v) => {
|
||||
const path = v.replace('../../views/', '/');
|
||||
return path.endsWith('.vue') ? path.slice(0, -4) : path;
|
||||
});
|
||||
export { accessRoutes, componentKeys, coreRouteNames, routes };
|
||||
|
||||
30
apps/web-naive/src/router/tongji.ts
Normal file
30
apps/web-naive/src/router/tongji.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import type { Router } from 'vue-router';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
_hmt: any[];
|
||||
}
|
||||
}
|
||||
|
||||
const HM_ID = import.meta.env.VITE_APP_BAIDU_CODE;
|
||||
|
||||
/**
|
||||
* 设置百度统计
|
||||
* @param router
|
||||
*/
|
||||
function setupBaiduTongJi(router: Router) {
|
||||
// 如果没有配置百度统计的 ID,则不进行设置
|
||||
if (!HM_ID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// _hmt:用于 router push
|
||||
window._hmt = window._hmt || [];
|
||||
|
||||
router.afterEach((to) => {
|
||||
// 添加到 _hmt 中
|
||||
window._hmt.push(['_trackPageview', to.fullPath]);
|
||||
});
|
||||
}
|
||||
|
||||
export { setupBaiduTongJi };
|
||||
Reference in New Issue
Block a user