🔖 项目重命名.

This commit is contained in:
lijiahangmax
2024-05-16 00:03:30 +08:00
parent f7189e34cb
commit d3a045ec20
1511 changed files with 4199 additions and 4128 deletions

View File

@@ -0,0 +1,60 @@
import type { RouteLocationNormalized } from 'vue-router';
import type { TagProps } from '@/store/modules/tab-bar/types';
export const REDIRECT_ROUTE_NAME = 'redirect';
export const LOGIN_ROUTE_NAME = 'login';
export const FORBIDDEN_ROUTER_NAME = 'forbidden';
export const NOT_FOUND_ROUTER_NAME = 'notFound';
export const DEFAULT_ROUTE_NAME = 'workplace';
export const DEFAULT_ROUTE_FULL_PATH = '/workplace';
/**
* 默认路由
*/
export const DEFAULT_ROUTER = { name: DEFAULT_ROUTE_NAME, children: [] };
/**
* 路由白名单
*/
export const WHITE_ROUTER_LIST = [
{ name: LOGIN_ROUTE_NAME, children: [] },
{ name: REDIRECT_ROUTE_NAME, children: [] },
];
/**
* 状态路由
*/
export const STATUS_ROUTER_LIST = [
{ name: NOT_FOUND_ROUTER_NAME, children: [] },
{ name: FORBIDDEN_ROUTER_NAME, children: [] },
];
/**
* 默认 tab 页面
*/
export const DEFAULT_TAB = {
title: '工作台',
name: DEFAULT_ROUTE_NAME,
path: DEFAULT_ROUTE_FULL_PATH,
fullPath: DEFAULT_ROUTE_FULL_PATH,
};
/**
* router 转 tag
*/
export const routerToTag = (route: RouteLocationNormalized): TagProps => {
const { name, meta, path, fullPath, query } = route;
return {
title: meta.locale || '',
name: String(name),
path,
fullPath,
query,
ignoreCache: meta.ignoreCache,
};
};

View File

@@ -0,0 +1,16 @@
import type { Router } from 'vue-router';
import setupUserLoginInfoGuard from './user-login-info';
import setupPermissionGuard from './router-permission';
import setupRouteEmitterGuard from './router-listener-emitter';
/**
* 创建路由守卫
*/
export default function createRouteGuard(router: Router) {
// 路由监听守卫
setupRouteEmitterGuard(router);
// 登录检查守卫
setupUserLoginInfoGuard(router);
// 权限检查守卫
setupPermissionGuard(router);
}

View 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);
});
}

View File

@@ -0,0 +1,39 @@
import type { Router } from 'vue-router';
import NProgress from 'nprogress';
import { useMenuStore } from '@/store';
import { NOT_FOUND_ROUTER_NAME, WHITE_ROUTER_LIST } from '../constants';
import usePermission from '@/hooks/permission';
export default function setupPermissionGuard(router: Router) {
router.beforeEach(async (to, from, next) => {
const menuStore = useMenuStore();
// 未加载菜单 并且 不在白名单内 则加载菜单
if (
!menuStore.menuFetched &&
!WHITE_ROUTER_LIST.find((el) => el.name === to.name)
) {
// 加载菜单
await menuStore.fetchMenu();
}
// 检测是否可以访问
const permission = usePermission();
const access = permission.accessRouter(to);
// 刚进入页面时 重定向的 meta 是空的
if (access && to.meta.locale === undefined && menuStore.menuFetched) {
to.meta = to.matched[to.matched.length - 1].meta;
}
if (access) {
// 正常跳转
next();
} else {
// 页面不存在
next({ name: NOT_FOUND_ROUTER_NAME });
}
// 修改页面标题
const locale = to.meta?.locale;
if (locale) {
document.title = locale;
}
NProgress.done();
});
}

View File

@@ -0,0 +1,50 @@
import type { Router, LocationQueryRaw } from 'vue-router';
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.id) {
next();
} else {
try {
// 获取用户信息
await userStore.info();
next();
} catch (error) {
// 获取失败退出登录
await userStore.logout();
next({
name: 'login',
query: {
redirect: to.name,
...to.query,
} as LocationQueryRaw,
});
}
}
} else {
// 未登录跳转到登录页
if (to.name === 'login') {
next();
return;
}
// 跳转到登录页
next({
name: 'login',
query: {
redirect: to.name,
...to.query,
} as LocationQueryRaw,
});
}
});
}

View File

@@ -0,0 +1,33 @@
import type { RouteLocationRaw } from 'vue-router';
import { createRouter, createWebHistory } from 'vue-router';
import NProgress from 'nprogress';
import { appRoutes } from './routes';
import BASE_ROUTERS from './routes/base';
import createRouteGuard from './guard';
import { openWindow } from '@/utils';
import 'nprogress/nprogress.css';
NProgress.configure({ showSpinner: false });
// 创建路由
const router = createRouter({
history: createWebHistory(),
routes: [
...BASE_ROUTERS,
...appRoutes,
],
scrollBehavior() {
return { top: 0 };
},
});
// 创建路由守卫
createRouteGuard(router);
// 新页面打开路由
export const openNewRoute = (route: RouteLocationRaw) => {
const { href } = router.resolve(route);
openWindow(href);
};
export default router;

View File

@@ -0,0 +1,76 @@
import type { RouteRecordRaw } from 'vue-router';
import { DEFAULT_ROUTE_FULL_PATH, FORBIDDEN_ROUTER_NAME, LOGIN_ROUTE_NAME, NOT_FOUND_ROUTER_NAME, REDIRECT_ROUTE_NAME, } from '@/router/constants';
// 默认布局
export const DEFAULT_LAYOUT = () => import('@/layout/default-layout.vue');
// 全屏布局
export const FULL_LAYOUT = () => import('@/layout/full-layout.vue');
// 根页面
export const ROOT_ROUTER: RouteRecordRaw = {
path: '/',
redirect: DEFAULT_ROUTE_FULL_PATH,
};
// 登录页面
export const LOGIN_ROUTER: RouteRecordRaw = {
path: '/login',
name: LOGIN_ROUTE_NAME,
meta: {
locale: '登录'
},
component: () => import('@/views/authentication/login/index.vue'),
};
// 重定向页面
export const REDIRECT_ROUTER: RouteRecordRaw = {
path: '/redirect',
name: 'redirectWrapper',
component: DEFAULT_LAYOUT,
meta: {
locale: '重定向',
hideInMenu: true,
},
children: [
{
path: '/redirect/:path',
name: REDIRECT_ROUTE_NAME,
component: () => import('@/views/base/redirect/index.vue'),
meta: {
locale: '重定向',
hideInMenu: true,
noAffix: true
},
},
],
};
// 403 页面
export const FORBIDDEN_ROUTE: RouteRecordRaw = {
path: '/403',
name: FORBIDDEN_ROUTER_NAME,
meta: {
locale: '403'
},
component: () => import('@/views/base/status/forbidden/index.vue'),
};
// 404 页面
export const NOT_FOUND_ROUTE: RouteRecordRaw = {
// path: '/:pathMatch(.*)*',
path: '/404',
name: NOT_FOUND_ROUTER_NAME,
meta: {
locale: '404'
},
component: () => import('@/views/base/status/not-found/index.vue'),
};
export default [
ROOT_ROUTER,
LOGIN_ROUTER,
REDIRECT_ROUTER,
NOT_FOUND_ROUTE,
FORBIDDEN_ROUTE
];

View File

@@ -0,0 +1,20 @@
import type { RouteRecordNormalized } from 'vue-router';
// 应用模块
const modules = import.meta.glob('./modules/*.ts', { eager: true });
// 应用路由
export const appRoutes: RouteRecordNormalized[] = formatModules(modules, []);
// 格式化模块
function formatModules(_modules: any, result: RouteRecordNormalized[]) {
Object.keys(_modules).forEach((key) => {
const defaultModule = _modules[key].default;
if (!defaultModule) return;
const moduleList = Array.isArray(defaultModule)
? [...defaultModule]
: [defaultModule];
result.push(...moduleList);
});
return result;
}

View File

@@ -0,0 +1,27 @@
import type { AppRouteRecordRaw } from '../types';
import { DEFAULT_LAYOUT } from '../base';
const ASSET_AUDIT: AppRouteRecordRaw = {
name: 'assetAuditModule',
path: '/asset-audit-module',
component: DEFAULT_LAYOUT,
children: [
{
name: 'connectLog',
path: '/connect-log',
component: () => import('@/views/asset-audit/connect-log/index.vue'),
},
{
name: 'connectSession',
path: '/connect-session',
component: () => import('@/views/asset-audit/connect-session/index.vue'),
},
{
name: 'sftpLog',
path: '/sftp-log',
component: () => import('@/views/asset-audit/sftp-log/index.vue'),
},
],
};
export default ASSET_AUDIT;

View File

@@ -0,0 +1,29 @@
import type { AppRouteRecordRaw } from '../types';
import { DEFAULT_LAYOUT } from '../base';
const ASSET: AppRouteRecordRaw = {
name: 'assetModule',
path: '/asset-module',
component: DEFAULT_LAYOUT,
children: [
{
name: 'hostList',
path: '/host-list',
component: () => import('@/views/asset/host-list/index.vue'),
}, {
name: 'hostKey',
path: '/host-key',
component: () => import('@/views/asset/host-key/index.vue'),
}, {
name: 'hostIdentity',
path: '/host-identity',
component: () => import('@/views/asset/host-identity/index.vue'),
}, {
name: 'assetGrant',
path: '/asset-grant',
component: () => import('@/views/asset/grant/index.vue'),
},
],
};
export default ASSET;

View File

@@ -0,0 +1,17 @@
import type { AppRouteRecordRaw } from '../types';
import { DEFAULT_LAYOUT } from '../base';
const DASHBOARD: AppRouteRecordRaw = {
name: 'dashboard',
path: '/dashboard',
component: DEFAULT_LAYOUT,
children: [
{
name: 'workplace',
path: '/workplace',
component: () => import('@/views/dashboard/workplace/index.vue'),
},
],
};
export default DASHBOARD;

View File

@@ -0,0 +1,37 @@
import type { AppRouteRecordRaw } from '../types';
import { DEFAULT_LAYOUT } from '../base';
const EXEC: AppRouteRecordRaw = {
name: 'execModule',
path: '/exec-module',
component: DEFAULT_LAYOUT,
children: [
{
name: 'execCommand',
path: '/exec-command',
component: () => import('@/views/exec/exec-command/index.vue'),
},
{
name: 'execCommandLog',
path: '/exec-log',
component: () => import('@/views/exec/exec-command-log/index.vue'),
},
{
name: 'batchUpload',
path: '/batch-upload',
component: () => import('@/views/exec/batch-upload/index.vue'),
},
{
name: 'uploadTask',
path: '/upload-task',
component: () => import('@/views/exec/upload-task/index.vue'),
},
{
name: 'execTemplate',
path: '/exec-template',
component: () => import('@/views/exec/exec-template/index.vue'),
},
],
};
export default EXEC;

View File

@@ -0,0 +1,20 @@
import type { AppRouteRecordRaw } from '../types';
import { FULL_LAYOUT } from '../base';
const HOST: AppRouteRecordRaw = {
name: 'hostModule',
path: '/host-module',
component: FULL_LAYOUT,
children: [
{
name: 'terminal',
path: '/terminal',
component: () => import('@/views/host/terminal/index.vue'),
meta: {
noAffix: true
}
},
],
};
export default HOST;

View File

@@ -0,0 +1,36 @@
import type { AppRouteRecordRaw } from '../types';
import { DEFAULT_LAYOUT, FULL_LAYOUT } from '../base';
const JOB: AppRouteRecordRaw[] = [
{
name: 'jobModule',
path: '/job-module',
component: DEFAULT_LAYOUT,
children: [
{
name: 'execJob',
path: '/exec-job',
component: () => import('@/views/job/exec-job/index.vue'),
},
{
name: 'execJobLog',
path: '/exec-job-log',
component: () => import('@/views/job/exec-job-log/index.vue'),
},
],
},
{
name: 'jobFullModule',
path: '/job-full-module',
component: FULL_LAYOUT,
children: [
{
name: 'execJobLogView',
path: '/job-log-view',
component: () => import('@/views/job/exec-job-log-view/index.vue'),
},
],
}
];
export default JOB;

View File

@@ -0,0 +1,27 @@
import type { AppRouteRecordRaw } from '../types';
import { DEFAULT_LAYOUT } from '../base';
const SYSTEM: AppRouteRecordRaw = {
name: 'systemModule',
path: '/system-module',
component: DEFAULT_LAYOUT,
children: [
{
name: 'systemMenu',
path: '/menu',
component: () => import('@/views/system/menu/index.vue'),
},
{
name: 'dictKey',
path: '/dict-key',
component: () => import('@/views/system/dict-key/index.vue'),
},
{
name: 'dictValue',
path: '/dict-value',
component: () => import('@/views/system/dict-value/index.vue'),
},
],
};
export default SYSTEM;

View File

@@ -0,0 +1,32 @@
import type { AppRouteRecordRaw } from '../types';
import { DEFAULT_LAYOUT } from '../base';
const USER: AppRouteRecordRaw = {
name: 'userModule',
path: '/user-module',
component: DEFAULT_LAYOUT,
children: [
{
name: 'role',
path: '/role',
component: () => import('@/views/user/role/index.vue'),
},
{
name: 'user',
path: '/user',
component: () => import('@/views/user/user/index.vue'),
},
{
name: 'userInfo',
path: '/user-info',
component: () => import('@/views/user/info/index.vue'),
},
{
name: 'operatorLog',
path: '/operator-log',
component: () => import('@/views/user/operator-log/index.vue'),
},
],
};
export default USER;

View File

@@ -0,0 +1,20 @@
import type { RouteMeta, NavigationGuard } from 'vue-router';
import { defineComponent } from 'vue';
export type Component<T = any> =
| ReturnType<typeof defineComponent>
| (() => Promise<typeof import('*.vue')>)
| (() => Promise<T>);
export interface AppRouteRecordRaw {
path?: string;
name?: string | symbol;
meta?: RouteMeta;
redirect?: string;
component: Component | string;
children?: AppRouteRecordRaw[];
alias?: string | string[];
props?: Record<string, any>;
beforeEnter?: NavigationGuard | NavigationGuard[];
fullPath?: string;
}

25
orion-visor-ui/src/router/typings.d.ts vendored Normal file
View File

@@ -0,0 +1,25 @@
import 'vue-router';
/**
* 前端覆盖后端
*/
declare module 'vue-router' {
interface RouteMeta {
// 图标
icon?: string;
// 名称
locale?: string;
// 排序
order?: number;
// 是否隐藏菜单
hideInMenu?: boolean;
// 是否添加到 tab
noAffix?: boolean;
// 是否忽略缓存
ignoreCache?: boolean;
// 是否新窗口打开
newWindow?: boolean;
// 是否活跃
activeMenu?: string;
}
}