初始化 ui.
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
import { appRoutes, appExternalRoutes } from '../routes';
|
||||
|
||||
const mixinRoutes = [...appRoutes, ...appExternalRoutes];
|
||||
|
||||
const appClientMenus = mixinRoutes.map((el) => {
|
||||
const { name, path, meta, redirect, children } = el;
|
||||
return {
|
||||
name,
|
||||
path,
|
||||
meta,
|
||||
redirect,
|
||||
children,
|
||||
};
|
||||
});
|
||||
|
||||
export default appClientMenus;
|
||||
@@ -1,18 +1,30 @@
|
||||
export const WHITE_LIST = [
|
||||
{ name: 'notFound', children: [] },
|
||||
{ name: 'login', children: [] },
|
||||
];
|
||||
export const REDIRECT_ROUTE_NAME = 'redirect';
|
||||
|
||||
export const NOT_FOUND = {
|
||||
name: 'notFound',
|
||||
};
|
||||
export const LOGIN_ROUTE_NAME = 'login';
|
||||
|
||||
export const REDIRECT_ROUTE_NAME = 'Redirect';
|
||||
export const FORBIDDEN_ROUTER_NAME = 'forbidden';
|
||||
|
||||
export const DEFAULT_ROUTE_NAME = 'Workplace';
|
||||
export const NOT_FOUND_ROUTER_NAME = 'notFound';
|
||||
|
||||
export const DEFAULT_ROUTE = {
|
||||
export const DEFAULT_ROUTE_NAME = 'workplace';
|
||||
|
||||
export const DEFAULT_ROUTE_FULL_PATH = '/dashboard/workplace';
|
||||
|
||||
/**
|
||||
* 默认 tab 页面
|
||||
*/
|
||||
export const DEFAULT_TAB = {
|
||||
title: 'menu.dashboard.workplace',
|
||||
name: DEFAULT_ROUTE_NAME,
|
||||
fullPath: '/dashboard/workplace',
|
||||
fullPath: DEFAULT_ROUTE_FULL_PATH,
|
||||
};
|
||||
|
||||
/**
|
||||
* 路由白名单
|
||||
*/
|
||||
export const WHITE_ROUTER_LIST = [
|
||||
{ name: LOGIN_ROUTE_NAME, children: [] },
|
||||
{ name: NOT_FOUND_ROUTER_NAME, children: [] },
|
||||
{ name: FORBIDDEN_ROUTER_NAME, children: [] },
|
||||
{ name: REDIRECT_ROUTE_NAME, children: [] },
|
||||
];
|
||||
|
||||
@@ -1,17 +1,13 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { setRouteEmitter } from '@/utils/route-listener';
|
||||
import setupUserLoginInfoGuard from './userLoginInfo';
|
||||
import setupPermissionGuard from './permission';
|
||||
|
||||
function setupPageGuard(router: Router) {
|
||||
router.beforeEach(async (to) => {
|
||||
// emit route change
|
||||
setRouteEmitter(to);
|
||||
});
|
||||
}
|
||||
import setupUserLoginInfoGuard from './user-login-info';
|
||||
import setupPermissionGuard from './router-permission';
|
||||
import setupRouteEmitterGuard from './router-listener-emitter';
|
||||
|
||||
/**
|
||||
* 创建路由守卫
|
||||
*/
|
||||
export default function createRouteGuard(router: Router) {
|
||||
setupPageGuard(router);
|
||||
setupRouteEmitterGuard(router);
|
||||
setupUserLoginInfoGuard(router);
|
||||
setupPermissionGuard(router);
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import type { Router, RouteRecordNormalized } from 'vue-router';
|
||||
import NProgress from 'nprogress'; // progress bar
|
||||
|
||||
import usePermission from '@/hooks/permission';
|
||||
import { useUserStore, useAppStore } from '@/store';
|
||||
import { appRoutes } from '../routes';
|
||||
import { WHITE_LIST, NOT_FOUND } from '../constants';
|
||||
|
||||
export default function setupPermissionGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const appStore = useAppStore();
|
||||
const userStore = useUserStore();
|
||||
const Permission = usePermission();
|
||||
const permissionsAllow = Permission.accessRouter(to);
|
||||
if (appStore.menuFromServer) {
|
||||
// 针对来自服务端的菜单配置进行处理
|
||||
// Handle routing configuration from the server
|
||||
|
||||
// 根据需要自行完善来源于服务端的菜单配置的permission逻辑
|
||||
// Refine the permission logic from the server's menu configuration as needed
|
||||
if (
|
||||
!appStore.appAsyncMenus.length &&
|
||||
!WHITE_LIST.find((el) => el.name === to.name)
|
||||
) {
|
||||
await appStore.fetchServerMenuConfig();
|
||||
}
|
||||
const serverMenuConfig = [...appStore.appAsyncMenus, ...WHITE_LIST];
|
||||
|
||||
let exist = false;
|
||||
while (serverMenuConfig.length && !exist) {
|
||||
const element = serverMenuConfig.shift();
|
||||
if (element?.name === to.name) exist = true;
|
||||
|
||||
if (element?.children) {
|
||||
serverMenuConfig.push(
|
||||
...(element.children as unknown as RouteRecordNormalized[])
|
||||
);
|
||||
}
|
||||
}
|
||||
if (exist && permissionsAllow) {
|
||||
next();
|
||||
} else next(NOT_FOUND);
|
||||
} else {
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (permissionsAllow) next();
|
||||
else {
|
||||
const destination =
|
||||
Permission.findFirstPermissionRoute(appRoutes, userStore.role) ||
|
||||
NOT_FOUND;
|
||||
next(destination);
|
||||
}
|
||||
}
|
||||
NProgress.done();
|
||||
});
|
||||
}
|
||||
11
orion-ops-ui/src/router/guard/router-listener-emitter.ts
Normal file
11
orion-ops-ui/src/router/guard/router-listener-emitter.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { setRouteEmitter } from '@/utils/route-listener';
|
||||
|
||||
/**
|
||||
* 初始化路由监听订阅
|
||||
*/
|
||||
export default function setupRouteEmitterGuard(router: Router) {
|
||||
router.beforeEach(async (to) => {
|
||||
setRouteEmitter(to);
|
||||
});
|
||||
}
|
||||
47
orion-ops-ui/src/router/guard/router-permission.ts
Normal file
47
orion-ops-ui/src/router/guard/router-permission.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import type { Router, RouteRecordNormalized } from 'vue-router';
|
||||
import NProgress from 'nprogress';
|
||||
import usePermission from '@/hooks/permission';
|
||||
import { useAppStore } from '@/store';
|
||||
import { WHITE_ROUTER_LIST, NOT_FOUND_ROUTER_NAME, FORBIDDEN_ROUTER_NAME } from '../constants';
|
||||
|
||||
export default function setupPermissionGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const appStore = useAppStore();
|
||||
const permission = usePermission();
|
||||
|
||||
// 未加载菜单 并且 未从白名单中找到 to.name
|
||||
if (
|
||||
!appStore.appAsyncMenus.length &&
|
||||
!WHITE_ROUTER_LIST.find((el) => el.name === to.name)
|
||||
) {
|
||||
// 加载菜单
|
||||
await appStore.fetchMenuConfig();
|
||||
}
|
||||
// 检查路由是否存在
|
||||
const menuConfig = [...appStore.appAsyncMenus, ...WHITE_ROUTER_LIST];
|
||||
let exist = false;
|
||||
while (menuConfig.length && !exist) {
|
||||
const element = menuConfig.shift();
|
||||
if (element?.name === to.name) exist = true;
|
||||
|
||||
if (element?.children) {
|
||||
menuConfig.push(
|
||||
...(element.children as unknown as RouteRecordNormalized[])
|
||||
);
|
||||
}
|
||||
}
|
||||
// 检查是否有权限
|
||||
const permissionsAllow = permission.accessRouter(to);
|
||||
if (!exist) {
|
||||
// 页面不存在
|
||||
next({ name: NOT_FOUND_ROUTER_NAME });
|
||||
} else if (!permissionsAllow) {
|
||||
// 无权限
|
||||
next({ name: FORBIDDEN_ROUTER_NAME });
|
||||
} else {
|
||||
// 正常跳转
|
||||
next();
|
||||
}
|
||||
NProgress.done();
|
||||
});
|
||||
}
|
||||
@@ -1,21 +1,26 @@
|
||||
import type { Router, LocationQueryRaw } from 'vue-router';
|
||||
import NProgress from 'nprogress'; // progress bar
|
||||
|
||||
import NProgress from 'nprogress';
|
||||
import { useUserStore } from '@/store';
|
||||
import { isLogin } from '@/utils/auth';
|
||||
|
||||
/**
|
||||
* 初始化用户登录路由守卫
|
||||
*/
|
||||
export default function setupUserLoginInfoGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
NProgress.start();
|
||||
const userStore = useUserStore();
|
||||
if (isLogin()) {
|
||||
if (userStore.role) {
|
||||
// 获取用户信息
|
||||
if (userStore.id) {
|
||||
next();
|
||||
} else {
|
||||
try {
|
||||
// 获取用户信息
|
||||
await userStore.info();
|
||||
next();
|
||||
} catch (error) {
|
||||
// 获取失败退出登录
|
||||
await userStore.logout();
|
||||
next({
|
||||
name: 'login',
|
||||
@@ -27,10 +32,12 @@ export default function setupUserLoginInfoGuard(router: Router) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 未登录跳转到登录页
|
||||
if (to.name === 'login') {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
// 跳转到登录页
|
||||
next({
|
||||
name: 'login',
|
||||
query: {
|
||||
@@ -1,37 +1,25 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
import NProgress from 'nprogress'; // progress bar
|
||||
import NProgress from 'nprogress';
|
||||
import 'nprogress/nprogress.css';
|
||||
|
||||
import { appRoutes } from './routes';
|
||||
import { REDIRECT_MAIN, NOT_FOUND_ROUTE } from './routes/base';
|
||||
import BASE_ROUTERS from './routes/base';
|
||||
import createRouteGuard from './guard';
|
||||
|
||||
NProgress.configure({ showSpinner: false }); // NProgress Configuration
|
||||
NProgress.configure({ showSpinner: false });
|
||||
|
||||
// 创建路由
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
redirect: 'login',
|
||||
},
|
||||
{
|
||||
path: '/login',
|
||||
name: 'login',
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
},
|
||||
},
|
||||
...BASE_ROUTERS,
|
||||
...appRoutes,
|
||||
REDIRECT_MAIN,
|
||||
NOT_FOUND_ROUTE,
|
||||
],
|
||||
scrollBehavior() {
|
||||
return { top: 0 };
|
||||
},
|
||||
});
|
||||
|
||||
// 创建路由守卫
|
||||
createRouteGuard(router);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -1,9 +1,38 @@
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { REDIRECT_ROUTE_NAME } from '@/router/constants';
|
||||
import {
|
||||
DEFAULT_ROUTE_FULL_PATH,
|
||||
REDIRECT_ROUTE_NAME,
|
||||
LOGIN_ROUTE_NAME,
|
||||
FORBIDDEN_ROUTER_NAME,
|
||||
NOT_FOUND_ROUTER_NAME,
|
||||
} from '@/router/constants';
|
||||
|
||||
export const DEFAULT_LAYOUT = () => import('@/layout/default-layout.vue');
|
||||
|
||||
export const REDIRECT_MAIN: RouteRecordRaw = {
|
||||
/**
|
||||
* 根页面
|
||||
*/
|
||||
export const ROOT_ROUTER: RouteRecordRaw = {
|
||||
path: '/',
|
||||
redirect: DEFAULT_ROUTE_FULL_PATH,
|
||||
};
|
||||
|
||||
/**
|
||||
* 登录页面
|
||||
*/
|
||||
export const LOGIN_ROUTER: RouteRecordRaw = {
|
||||
path: '/login',
|
||||
name: LOGIN_ROUTE_NAME,
|
||||
component: () => import('@/views/login/index.vue'),
|
||||
meta: {
|
||||
requiresAuth: false,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 重定向页面
|
||||
*/
|
||||
export const REDIRECT_ROUTER: RouteRecordRaw = {
|
||||
path: '/redirect',
|
||||
name: 'redirectWrapper',
|
||||
component: DEFAULT_LAYOUT,
|
||||
@@ -24,8 +53,28 @@ export const REDIRECT_MAIN: RouteRecordRaw = {
|
||||
],
|
||||
};
|
||||
|
||||
/**
|
||||
* 403 页面
|
||||
*/
|
||||
export const FORBIDDEN_ROUTE: RouteRecordRaw = {
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: FORBIDDEN_ROUTER_NAME,
|
||||
component: () => import('@/views/base/forbidden/index.vue'),
|
||||
};
|
||||
|
||||
/**
|
||||
* 404 页面
|
||||
*/
|
||||
export const NOT_FOUND_ROUTE: RouteRecordRaw = {
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'notFound',
|
||||
component: () => import('@/views/not-found/index.vue'),
|
||||
name: NOT_FOUND_ROUTER_NAME,
|
||||
component: () => import('@/views/base/not-found/index.vue'),
|
||||
};
|
||||
|
||||
export default [
|
||||
ROOT_ROUTER,
|
||||
LOGIN_ROUTER,
|
||||
REDIRECT_ROUTER,
|
||||
NOT_FOUND_ROUTE,
|
||||
FORBIDDEN_ROUTE
|
||||
];
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
export default {
|
||||
path: 'https://arco.design',
|
||||
name: 'arcoWebsite',
|
||||
meta: {
|
||||
locale: 'menu.arcoWebsite',
|
||||
icon: 'icon-link',
|
||||
requiresAuth: true,
|
||||
order: 8,
|
||||
},
|
||||
};
|
||||
@@ -1,10 +0,0 @@
|
||||
export default {
|
||||
path: 'https://arco.design/vue/docs/pro/faq',
|
||||
name: 'faq',
|
||||
meta: {
|
||||
locale: 'menu.faq',
|
||||
icon: 'icon-question-circle',
|
||||
requiresAuth: true,
|
||||
order: 9,
|
||||
},
|
||||
};
|
||||
@@ -1,9 +1,7 @@
|
||||
import type { RouteRecordNormalized } from 'vue-router';
|
||||
|
||||
// 应用模块
|
||||
const modules = import.meta.glob('./modules/*.ts', { eager: true });
|
||||
const externalModules = import.meta.glob('./externalModules/*.ts', {
|
||||
eager: true,
|
||||
});
|
||||
|
||||
function formatModules(_modules: any, result: RouteRecordNormalized[]) {
|
||||
Object.keys(_modules).forEach((key) => {
|
||||
@@ -17,9 +15,7 @@ function formatModules(_modules: any, result: RouteRecordNormalized[]) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用路由
|
||||
*/
|
||||
export const appRoutes: RouteRecordNormalized[] = formatModules(modules, []);
|
||||
|
||||
export const appExternalRoutes: RouteRecordNormalized[] = formatModules(
|
||||
externalModules,
|
||||
[]
|
||||
);
|
||||
|
||||
@@ -14,23 +14,11 @@ const DASHBOARD: AppRouteRecordRaw = {
|
||||
children: [
|
||||
{
|
||||
path: 'workplace',
|
||||
name: 'Workplace',
|
||||
name: 'workplace',
|
||||
component: () => import('@/views/dashboard/workplace/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.dashboard.workplace',
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
path: 'monitor',
|
||||
name: 'Monitor',
|
||||
component: () => import('@/views/dashboard/monitor/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.dashboard.monitor',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { DEFAULT_LAYOUT } from '../base';
|
||||
import { AppRouteRecordRaw } from '../types';
|
||||
|
||||
const EXCEPTION: AppRouteRecordRaw = {
|
||||
path: '/exception',
|
||||
name: 'exception',
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.exception',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-exclamation-circle',
|
||||
order: 6,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: '403',
|
||||
name: '403',
|
||||
component: () => import('@/views/exception/403/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.exception.403',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '404',
|
||||
name: '404',
|
||||
component: () => import('@/views/exception/404/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.exception.404',
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: '500',
|
||||
name: '500',
|
||||
component: () => import('@/views/exception/500/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.exception.500',
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default EXCEPTION;
|
||||
@@ -1,38 +0,0 @@
|
||||
import { DEFAULT_LAYOUT } from '../base';
|
||||
import { AppRouteRecordRaw } from '../types';
|
||||
|
||||
const FORM: AppRouteRecordRaw = {
|
||||
path: '/form',
|
||||
name: 'form',
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.form',
|
||||
icon: 'icon-settings',
|
||||
requiresAuth: true,
|
||||
order: 3,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'step',
|
||||
name: 'Step',
|
||||
component: () => import('@/views/form/step/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.form.step',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'group',
|
||||
name: 'Group',
|
||||
component: () => import('@/views/form/group/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.form.group',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default FORM;
|
||||
@@ -1,38 +0,0 @@
|
||||
import { DEFAULT_LAYOUT } from '../base';
|
||||
import { AppRouteRecordRaw } from '../types';
|
||||
|
||||
const LIST: AppRouteRecordRaw = {
|
||||
path: '/list',
|
||||
name: 'list',
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.list',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-list',
|
||||
order: 2,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'search-table', // The midline path complies with SEO specifications
|
||||
name: 'SearchTable',
|
||||
component: () => import('@/views/list/search-table/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.list.searchTable',
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'card',
|
||||
name: 'Card',
|
||||
component: () => import('@/views/list/card/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.list.cardList',
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default LIST;
|
||||
@@ -1,28 +0,0 @@
|
||||
import { DEFAULT_LAYOUT } from '../base';
|
||||
import { AppRouteRecordRaw } from '../types';
|
||||
|
||||
const PROFILE: AppRouteRecordRaw = {
|
||||
path: '/profile',
|
||||
name: 'profile',
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.profile',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-file',
|
||||
order: 4,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'basic',
|
||||
name: 'Basic',
|
||||
component: () => import('@/views/profile/basic/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.profile.basic',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default PROFILE;
|
||||
@@ -1,38 +0,0 @@
|
||||
import { DEFAULT_LAYOUT } from '../base';
|
||||
import { AppRouteRecordRaw } from '../types';
|
||||
|
||||
const RESULT: AppRouteRecordRaw = {
|
||||
path: '/result',
|
||||
name: 'result',
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.result',
|
||||
icon: 'icon-check-circle',
|
||||
requiresAuth: true,
|
||||
order: 5,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'success',
|
||||
name: 'Success',
|
||||
component: () => import('@/views/result/success/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.result.success',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'error',
|
||||
name: 'Error',
|
||||
component: () => import('@/views/result/error/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.result.error',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default RESULT;
|
||||
@@ -6,30 +6,19 @@ const USER: AppRouteRecordRaw = {
|
||||
name: 'user',
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.user',
|
||||
icon: 'icon-user',
|
||||
locale: 'USER',
|
||||
requiresAuth: true,
|
||||
order: 7,
|
||||
icon: 'icon-dashboard',
|
||||
order: 0,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'info',
|
||||
name: 'Info',
|
||||
component: () => import('@/views/user/info/index.vue'),
|
||||
path: 'userChild',
|
||||
name: 'userChild',
|
||||
component: () => import('@/views/user/child/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.user.info',
|
||||
locale: '用户子页面',
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'setting',
|
||||
name: 'Setting',
|
||||
component: () => import('@/views/user/setting/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.user.setting',
|
||||
requiresAuth: true,
|
||||
roles: ['*'],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import { DEFAULT_LAYOUT } from '../base';
|
||||
import { AppRouteRecordRaw } from '../types';
|
||||
|
||||
const VISUALIZATION: AppRouteRecordRaw = {
|
||||
path: '/visualization',
|
||||
name: 'visualization',
|
||||
component: DEFAULT_LAYOUT,
|
||||
meta: {
|
||||
locale: 'menu.visualization',
|
||||
requiresAuth: true,
|
||||
icon: 'icon-apps',
|
||||
order: 1,
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'data-analysis',
|
||||
name: 'DataAnalysis',
|
||||
component: () => import('@/views/visualization/data-analysis/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.visualization.dataAnalysis',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: 'multi-dimension-data-analysis',
|
||||
name: 'MultiDimensionDataAnalysis',
|
||||
component: () =>
|
||||
import('@/views/visualization/multi-dimension-data-analysis/index.vue'),
|
||||
meta: {
|
||||
locale: 'menu.visualization.multiDimensionDataAnalysis',
|
||||
requiresAuth: true,
|
||||
roles: ['admin'],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default VISUALIZATION;
|
||||
20
orion-ops-ui/src/router/typings.d.ts
vendored
20
orion-ops-ui/src/router/typings.d.ts
vendored
@@ -2,15 +2,15 @@ import 'vue-router';
|
||||
|
||||
declare module 'vue-router' {
|
||||
interface RouteMeta {
|
||||
roles?: string[]; // Controls roles that have access to the page
|
||||
requiresAuth: boolean; // Whether login is required to access the current page (every route must declare)
|
||||
icon?: string; // The icon show in the side menu
|
||||
locale?: string; // The locale name show in side menu and breadcrumb
|
||||
hideInMenu?: boolean; // If true, it is not displayed in the side menu
|
||||
hideChildrenInMenu?: boolean; // if set true, the children are not displayed in the side menu
|
||||
activeMenu?: string; // if set name, the menu will be highlighted according to the name you set
|
||||
order?: number; // Sort routing menu items. If set key, the higher the value, the more forward it is
|
||||
noAffix?: boolean; // if set true, the tag will not affix in the tab-bar
|
||||
ignoreCache?: boolean; // if set true, the page will not be cached
|
||||
permission?: string;
|
||||
requiresAuth: boolean;
|
||||
icon?: string;
|
||||
locale?: string;
|
||||
hideInMenu?: boolean;
|
||||
hideChildrenInMenu?: boolean;
|
||||
activeMenu?: string;
|
||||
order?: number;
|
||||
noAffix?: boolean;
|
||||
ignoreCache?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user