首次提交

This commit is contained in:
2023-06-04 20:01:58 +08:00
parent 00c64c53bb
commit 587f078d21
560 changed files with 106725 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
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

View File

@@ -0,0 +1,18 @@
export const WHITE_LIST = [
{ name: 'notFound', children: [] },
{ name: 'login', children: [] },
]
export const NOT_FOUND = {
name: 'notFound',
}
export const REDIRECT_ROUTE_NAME = 'Redirect'
export const DEFAULT_ROUTE_NAME = 'Workplace'
export const DEFAULT_ROUTE = {
title: 'menu.dashboard.workplace',
name: DEFAULT_ROUTE_NAME,
fullPath: '/dashboard/workplace',
}

View File

@@ -0,0 +1,17 @@
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)
})
}
export default function createRouteGuard(router: Router) {
setupPageGuard(router)
setupUserLoginInfoGuard(router)
setupPermissionGuard(router)
}

View File

@@ -0,0 +1,48 @@
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()
})
}

View File

@@ -0,0 +1,43 @@
import type { Router, LocationQueryRaw } from 'vue-router'
import NProgress from 'nprogress' // progress bar
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) {
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,37 @@
import { createRouter, createWebHistory } from 'vue-router'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css'
import { appRoutes } from './routes'
import { REDIRECT_MAIN, NOT_FOUND_ROUTE } from './routes/base'
import createRouteGuard from './guard'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
redirect: 'login',
},
{
path: '/login',
name: 'login',
component: () => import('@/views/login/index.vue'),
meta: {
requiresAuth: false,
},
},
...appRoutes,
REDIRECT_MAIN,
NOT_FOUND_ROUTE,
],
scrollBehavior() {
return { top: 0 }
},
})
createRouteGuard(router)
export default router

View File

@@ -0,0 +1,31 @@
import type { RouteRecordRaw } from 'vue-router'
import { REDIRECT_ROUTE_NAME } from '@/router/constants'
export const DEFAULT_LAYOUT = () => import('@/layout/default-layout.vue')
export const REDIRECT_MAIN: RouteRecordRaw = {
path: '/redirect',
name: 'redirectWrapper',
component: DEFAULT_LAYOUT,
meta: {
requiresAuth: true,
hideInMenu: true,
},
children: [
{
path: '/redirect/:path',
name: REDIRECT_ROUTE_NAME,
component: () => import('@/views/redirect/index.vue'),
meta: {
requiresAuth: true,
hideInMenu: true,
},
},
],
}
export const NOT_FOUND_ROUTE: RouteRecordRaw = {
path: '/:pathMatch(.*)*',
name: 'notFound',
component: () => import('@/views/not-found/index.vue'),
}

View File

@@ -0,0 +1,20 @@
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) => {
const defaultModule = _modules[key].default
if (!defaultModule) return
const moduleList = Array.isArray(defaultModule) ? [...defaultModule] : [defaultModule]
result.push(...moduleList)
})
return result
}
export const appRoutes: RouteRecordNormalized[] = formatModules(modules, [])
export const appExternalRoutes: RouteRecordNormalized[] = formatModules(externalModules, [])

View File

@@ -0,0 +1,38 @@
import { DEFAULT_LAYOUT } from '../base'
import { AppRouteRecordRaw } from '../types'
const DASHBOARD: AppRouteRecordRaw = {
path: '/dashboard',
name: 'dashboard',
component: DEFAULT_LAYOUT,
meta: {
locale: 'menu.dashboard',
requiresAuth: true,
icon: 'icon-dashboard',
order: 0,
},
children: [
{
path: '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'],
},
},
],
}
export default DASHBOARD

View File

@@ -0,0 +1,38 @@
import { DEFAULT_LAYOUT } from '../base'
import { AppRouteRecordRaw } from '../types'
const USER: AppRouteRecordRaw = {
path: '/user',
name: 'user',
component: DEFAULT_LAYOUT,
meta: {
locale: 'menu.userAbout',
requiresAuth: true,
icon: 'icon-user',
order: 1,
},
children: [
{
path: 'manage',
name: 'manage',
component: () => import('@/views/userAbout/userManage/index.vue'),
meta: {
locale: 'menu.userAbout.manage',
requiresAuth: true,
roles: ['admin', 'user'],
},
},
{
path: 'test',
name: 'test',
component: () => import('@/views/userAbout/test/index.vue'),
meta: {
locale: 'menu.userAbout.test',
requiresAuth: true,
roles: ['*'],
},
},
],
}
export default USER

View File

@@ -0,0 +1,20 @@
import { defineComponent } from 'vue'
import type { RouteMeta, NavigationGuard } from 'vue-router'
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
}

16
cdtestplant/src/router/typings.d.ts vendored Normal file
View File

@@ -0,0 +1,16 @@
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
}
}