|
@@ -1,25 +1,109 @@
|
|
|
import { AxiosWrapper } from '@/utils/axios-wrapper'
|
|
|
import { checkResult } from '@/utils/checkResult'
|
|
|
import { UserStore } from '@/store/user'
|
|
|
-
|
|
|
-export const registerBeforeRouter = (router) => {
|
|
|
+import { cloneDeep, omit } from 'lodash-es'
|
|
|
+// 检查路由是否存在
|
|
|
+const hasNecessaryRoute = (to, router) => {
|
|
|
+ // 将默认注册的路由平铺成一维数组
|
|
|
+ const routesOneDimensional = toOneDimensional(router.getRoutes())
|
|
|
+ return routesOneDimensional.find((f) => f.path === to.path)
|
|
|
+}
|
|
|
+// 获取用户信息,返回菜单
|
|
|
+const getUserMeta = async (token) => {
|
|
|
+ const userStore = UserStore()
|
|
|
+ const axios = new AxiosWrapper()
|
|
|
+ const result = await axios.$get(`/token/tokenView`, null, {
|
|
|
+ headers: {
|
|
|
+ token: token
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (checkResult(result)) {
|
|
|
+ userStore.setUser(result.data)
|
|
|
+ const resetMenusResult = resetMenus(result.data.menus)
|
|
|
+ const storeMenus = toRaw(userStore.menus)
|
|
|
+ if (storeMenus.length <= 0) {
|
|
|
+ userStore.setMenus(resetMenusResult)
|
|
|
+ }
|
|
|
+ return result.data.menus
|
|
|
+ }
|
|
|
+}
|
|
|
+// 注册前置守卫
|
|
|
+export const registerBeforeRouter = async (router) => {
|
|
|
router.beforeEach(async (to, from, next) => {
|
|
|
- const userStore = UserStore()
|
|
|
- const axios = new AxiosWrapper()
|
|
|
document.title = `${to.meta.title} `
|
|
|
const token = localStorage.getItem('token')
|
|
|
- if (to.name != 'login') {
|
|
|
- if (token) {
|
|
|
- const result = await axios.get(`${import.meta.env.VITE_REQUEST_BASE}/token/tokenView`, null, {
|
|
|
- headers: {
|
|
|
- token: token
|
|
|
- }
|
|
|
- })
|
|
|
- if (checkResult(result)) {
|
|
|
- userStore.setUser(result.data)
|
|
|
- }
|
|
|
+ if (token) {
|
|
|
+ if (to.path === '/login') next()
|
|
|
+ const menus = await getUserMeta(token)
|
|
|
+ // 检查目的地路由是否注册
|
|
|
+ const hasRoute = hasNecessaryRoute(to, router)
|
|
|
+ if (hasRoute) {
|
|
|
+ // 注册了直接进入
|
|
|
next()
|
|
|
- } else next('/login')
|
|
|
- } else next()
|
|
|
+ } else {
|
|
|
+ // 没注册就先注册再重定向进入直到进入为止
|
|
|
+ await addUserRoutes(menus, router)
|
|
|
+ next({ ...to, replace: true })
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ next('/login')
|
|
|
+ }
|
|
|
})
|
|
|
}
|
|
|
+/**
|
|
|
+ * 将路由数组一维化
|
|
|
+ * @param {Array} routes 路由数组
|
|
|
+ * @returns 一维路由数组
|
|
|
+ */
|
|
|
+const toOneDimensional = (routes) => {
|
|
|
+ const result = []
|
|
|
+ for (const r of routes) {
|
|
|
+ const { children = [], ...others } = r
|
|
|
+ result.push(others)
|
|
|
+ if (children.length > 0) result.push(...toOneDimensional(children))
|
|
|
+ }
|
|
|
+ return result
|
|
|
+}
|
|
|
+// 添加路由
|
|
|
+export const addUserRoutes = async (menus, router) => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ // 将用户菜单转换成普通对象
|
|
|
+ const menuArr = toRaw(menus)
|
|
|
+ // 将用户菜单平铺成一维数组,并将目录过滤出去.目录不需要注册,不是组件
|
|
|
+ const menuOneDimensional = toOneDimensional(menuArr).filter((f) => f.type !== '0')
|
|
|
+ // 将默认注册的路由平铺成一维数组
|
|
|
+ const routesOneDimensional = toOneDimensional(router.getRoutes())
|
|
|
+ // 过滤出需要注册的路由数据
|
|
|
+ const needRegistRoute = menuOneDimensional.filter((f) => !routesOneDimensional.find((od) => od.path === f.path))
|
|
|
+ const loadComponent = import.meta.glob('../views/**/*.vue')
|
|
|
+ // 注册路由
|
|
|
+ for (const r of needRegistRoute) {
|
|
|
+ let { path, component, route_name: name, name: title, in_admin_frame } = r
|
|
|
+ // 判断有没有route_name,没有就用component地址最后两个拼一起
|
|
|
+ if (!name) {
|
|
|
+ const list = component.split('/')
|
|
|
+ name = list.shift().join('')
|
|
|
+ }
|
|
|
+ const c = {
|
|
|
+ path,
|
|
|
+ name,
|
|
|
+ meta: { title },
|
|
|
+ component: loadComponent[`../views${component}.vue`]
|
|
|
+ }
|
|
|
+ if (in_admin_frame === '0') router.addRoute('AdminFrame', c)
|
|
|
+ else router.addRoute(c)
|
|
|
+ }
|
|
|
+ resolve()
|
|
|
+ })
|
|
|
+}
|
|
|
+const resetMenus = (menus) => {
|
|
|
+ const cMenus = cloneDeep(menus)
|
|
|
+ const result = []
|
|
|
+ for (const m of cMenus) {
|
|
|
+ const mid = omit(m, ['is_use', 'order_num', 'in_admin_frame', 'route_name'])
|
|
|
+ const { children } = mid
|
|
|
+ if (children) mid.children = resetMenus(children)
|
|
|
+ result.push(mid)
|
|
|
+ }
|
|
|
+ return result
|
|
|
+}
|