1
0
mirror of https://github.com/fumiama/paper-manager.git synced 2026-06-25 05:20:16 +08:00

add frontend/vben from vben-admin-thin

This commit is contained in:
源文雨
2023-03-10 17:18:32 +08:00
parent 30cd57ef76
commit 2a0fdeae31
469 changed files with 42028 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
import type { Router, RouteLocationNormalized } from 'vue-router'
import { useAppStoreWithOut } from '/@/store/modules/app'
import { useUserStoreWithOut } from '/@/store/modules/user'
import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'
import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel'
import { Modal, notification } from 'ant-design-vue'
import { warn } from '/@/utils/log'
import { unref } from 'vue'
import { setRouteChange } from '/@/logics/mitt/routeChange'
import { createPermissionGuard } from './permissionGuard'
import { createStateGuard } from './stateGuard'
import nProgress from 'nprogress'
import projectSetting from '/@/settings/projectSetting'
import { createParamMenuGuard } from './paramMenuGuard'
// Don't change the order of creation
export function setupRouterGuard(router: Router) {
createPageGuard(router)
createPageLoadingGuard(router)
createHttpGuard(router)
createScrollGuard(router)
createMessageGuard(router)
createProgressGuard(router)
createPermissionGuard(router)
createParamMenuGuard(router) // must after createPermissionGuard (menu has been built.)
createStateGuard(router)
}
/**
* Hooks for handling page state
*/
function createPageGuard(router: Router) {
const loadedPageMap = new Map<string, boolean>()
router.beforeEach(async (to) => {
// The page has already been loaded, it will be faster to open it again, you dont need to do loading and other processing
to.meta.loaded = !!loadedPageMap.get(to.path)
// Notify routing changes
setRouteChange(to)
return true
})
router.afterEach((to) => {
loadedPageMap.set(to.path, true)
})
}
// Used to handle page loading status
function createPageLoadingGuard(router: Router) {
const userStore = useUserStoreWithOut()
const appStore = useAppStoreWithOut()
const { getOpenPageLoading } = useTransitionSetting()
router.beforeEach(async (to) => {
if (!userStore.getToken) {
return true
}
if (to.meta.loaded) {
return true
}
if (unref(getOpenPageLoading)) {
appStore.setPageLoadingAction(true)
return true
}
return true
})
router.afterEach(async () => {
if (unref(getOpenPageLoading)) {
// TODO Looking for a better way
// The timer simulates the loading time to prevent flashing too fast,
setTimeout(() => {
appStore.setPageLoading(false)
}, 220)
}
return true
})
}
/**
* The interface used to close the current page to complete the request when the route is switched
* @param router
*/
function createHttpGuard(router: Router) {
const { removeAllHttpPending } = projectSetting
let axiosCanceler: Nullable<AxiosCanceler>
if (removeAllHttpPending) {
axiosCanceler = new AxiosCanceler()
}
router.beforeEach(async () => {
// Switching the route will delete the previous request
axiosCanceler?.removeAllPending()
return true
})
}
// Routing switch back to the top
function createScrollGuard(router: Router) {
const isHash = (href: string) => {
return /^#/.test(href)
}
const body = document.body
router.afterEach(async (to) => {
// scroll top
isHash((to as RouteLocationNormalized & { href: string })?.href) && body.scrollTo(0, 0)
return true
})
}
/**
* Used to close the message instance when the route is switched
* @param router
*/
export function createMessageGuard(router: Router) {
const { closeMessageOnSwitch } = projectSetting
router.beforeEach(async () => {
try {
if (closeMessageOnSwitch) {
Modal.destroyAll()
notification.destroy()
}
} catch (error) {
warn('message guard error:' + error)
}
return true
})
}
export function createProgressGuard(router: Router) {
const { getOpenNProgress } = useTransitionSetting()
router.beforeEach(async (to) => {
if (to.meta.loaded) {
return true
}
unref(getOpenNProgress) && nProgress.start()
return true
})
router.afterEach(async () => {
unref(getOpenNProgress) && nProgress.done()
return true
})
}

View File

@@ -0,0 +1,47 @@
import type { Router } from 'vue-router'
import { configureDynamicParamsMenu } from '../helper/menuHelper'
import { Menu } from '../types'
import { PermissionModeEnum } from '/@/enums/appEnum'
import { useAppStoreWithOut } from '/@/store/modules/app'
import { usePermissionStoreWithOut } from '/@/store/modules/permission'
export function createParamMenuGuard(router: Router) {
const permissionStore = usePermissionStoreWithOut()
router.beforeEach(async (to, _, next) => {
// filter no name route
if (!to.name) {
next()
return
}
// menu has been built.
if (!permissionStore.getIsDynamicAddedRoute) {
next()
return
}
let menus: Menu[] = []
if (isBackMode()) {
menus = permissionStore.getBackMenuList
} else if (isRouteMappingMode()) {
menus = permissionStore.getFrontMenuList
}
menus.forEach((item) => configureDynamicParamsMenu(item, to.params))
next()
})
}
const getPermissionMode = () => {
const appStore = useAppStoreWithOut()
return appStore.getProjectConfig.permissionMode
}
const isBackMode = () => {
return getPermissionMode() === PermissionModeEnum.BACK
}
const isRouteMappingMode = () => {
return getPermissionMode() === PermissionModeEnum.ROUTE_MAPPING
}

View File

@@ -0,0 +1,118 @@
import type { Router, RouteRecordRaw } from 'vue-router'
import { usePermissionStoreWithOut } from '/@/store/modules/permission'
import { PageEnum } from '/@/enums/pageEnum'
import { useUserStoreWithOut } from '/@/store/modules/user'
import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'
import { RootRoute } from '/@/router/routes'
const LOGIN_PATH = PageEnum.BASE_LOGIN
const ROOT_PATH = RootRoute.path
const whitePathList: PageEnum[] = [LOGIN_PATH]
export function createPermissionGuard(router: Router) {
const userStore = useUserStoreWithOut()
const permissionStore = usePermissionStoreWithOut()
router.beforeEach(async (to, from, next) => {
if (
from.path === ROOT_PATH &&
to.path === PageEnum.BASE_HOME &&
userStore.getUserInfo.homePath &&
userStore.getUserInfo.homePath !== PageEnum.BASE_HOME
) {
next(userStore.getUserInfo.homePath)
return
}
const token = userStore.getToken
// Whitelist can be directly entered
if (whitePathList.includes(to.path as PageEnum)) {
if (to.path === LOGIN_PATH && token) {
const isSessionTimeout = userStore.getSessionTimeout
try {
await userStore.afterLoginAction()
if (!isSessionTimeout) {
next((to.query?.redirect as string) || '/')
return
}
} catch {}
}
next()
return
}
// token does not exist
if (!token) {
// You can access without permission. You need to set the routing meta.ignoreAuth to true
if (to.meta.ignoreAuth) {
next()
return
}
// redirect login page
const redirectData: { path: string; replace: boolean; query?: Recordable<string> } = {
path: LOGIN_PATH,
replace: true,
}
if (to.path) {
redirectData.query = {
...redirectData.query,
redirect: to.path,
}
}
next(redirectData)
return
}
// Jump to the 404 page after processing the login
if (
from.path === LOGIN_PATH &&
to.name === PAGE_NOT_FOUND_ROUTE.name &&
to.fullPath !== (userStore.getUserInfo.homePath || PageEnum.BASE_HOME)
) {
next(userStore.getUserInfo.homePath || PageEnum.BASE_HOME)
return
}
// get userinfo while last fetch time is empty
if (userStore.getLastUpdateTime === 0) {
try {
await userStore.getUserInfoAction()
} catch (err) {
next()
return
}
}
if (permissionStore.getIsDynamicAddedRoute) {
next()
return
}
const routes = await permissionStore.buildRoutesAction()
routes.forEach((route) => {
router.addRoute(route as unknown as RouteRecordRaw)
})
router.addRoute(PAGE_NOT_FOUND_ROUTE as unknown as RouteRecordRaw)
permissionStore.setDynamicAddedRoute(true)
if (to.name === PAGE_NOT_FOUND_ROUTE.name) {
// 动态添加路由后此处应当重定向到fullPath否则会加载404页面内容
next({ path: to.fullPath, replace: true, query: to.query })
} else {
const redirectPath = (from.query.redirect || to.path) as string
const redirect = decodeURIComponent(redirectPath)
const nextData = to.path === redirect ? { ...to, replace: true } : { path: redirect }
next(nextData)
}
})
}

View File

@@ -0,0 +1,24 @@
import type { Router } from 'vue-router'
import { useAppStore } from '/@/store/modules/app'
import { useMultipleTabStore } from '/@/store/modules/multipleTab'
import { useUserStore } from '/@/store/modules/user'
import { usePermissionStore } from '/@/store/modules/permission'
import { PageEnum } from '/@/enums/pageEnum'
import { removeTabChangeListener } from '/@/logics/mitt/routeChange'
export function createStateGuard(router: Router) {
router.afterEach((to) => {
// Just enter the login page and clear the authentication information
if (to.path === PageEnum.BASE_LOGIN) {
const tabStore = useMultipleTabStore()
const userStore = useUserStore()
const appStore = useAppStore()
const permissionStore = usePermissionStore()
appStore.resetAllState()
permissionStore.resetState()
tabStore.resetState()
userStore.resetState()
removeTabChangeListener()
}
})
}