You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
reagent_manage/vue/src/store/module/resource.js

179 lines
4.8 KiB

6 years ago
import path from 'path'
import constantRoutes from '@/router/constant'
import authorityRoutes from '@/router/authority'
import {needAuth} from "@/util/auth"
import {createTree} from "@/util/tree"
import {getAllResources} from "@/api/system/resource"
import {isEmpty} from "@/util"
import {isExternal} from "@/util/validate"
6 years ago
const finalConstantRoutes = transformOriginRoutes(constantRoutes)
const finalAuthorityRoutes = transformOriginRoutes(authorityRoutes)
clean(finalConstantRoutes, false)
clean(finalAuthorityRoutes, false)
const state = {
routes: [],
sidebarMenus: [],
dataMap: {},
tree: [],
6 years ago
init: false
6 years ago
}
const mutations = {
routes(state, routes) {
const tempConstantRoutes = JSON.parse(JSON.stringify(finalConstantRoutes))
const tempAuthorityRoutes = JSON.parse(JSON.stringify(routes))
6 years ago
clean(tempConstantRoutes)
clean(tempAuthorityRoutes)
6 years ago
state.routes = finalConstantRoutes.concat(routes)
const sidebarMenus = tempConstantRoutes.concat(tempAuthorityRoutes)
sort(sidebarMenus)
state.sidebarMenus = sidebarMenus
6 years ago
},
data(state, data) {
data = data || []
state.dataMap = data.reduce((map, item) => {
map[item.url] = item.id
return map
}, {})
state.tree = createTree(data.filter(resource => resource.admin === false))
6 years ago
},
6 years ago
setInit(state, sign) {
state.init = sign
6 years ago
}
}
const actions = {
init({dispatch}, user) {
return Promise.all([
dispatch('initRoutes', user),
dispatch('initResource')
])
},
initRoutes({commit}, user) {
const {resources, admin} = user
return new Promise(resolve => {
const accessedRoutes = getAuthorizedRoutes({resources, admin})
commit('routes', accessedRoutes)
6 years ago
commit('setInit', true)
6 years ago
resolve()
})
},
initResource({commit}) {
6 years ago
return new Promise(resolve => {
getAllResources()
6 years ago
.then(data => {
commit('data', data)
6 years ago
resolve()
})
})
}
}
6 years ago
//在原始路由数组基础上添加全路径
6 years ago
function transformOriginRoutes(routes) {
const res = JSON.parse(JSON.stringify(routes))
6 years ago
addFullPath(res)
return res
}
//删除不显示的路由(没有children且没有meta.title,左侧菜单需清除meta.hidden=true)
6 years ago
function clean(routes, cleanHidden = true) {
for (let i = routes.length - 1; i >= 0; i--) {
const {children, meta: {title, alwaysShow, hidden} = {}} = routes[i]
if (cleanHidden && hidden) {
6 years ago
routes.splice(i, 1)
continue
}
if (!children && !title) {
6 years ago
routes.splice(i, 1)
continue
}
if (children) {
clean(children, cleanHidden)
if (children.length < 1 && !alwaysShow) {
6 years ago
routes.splice(i, 1)
}
}
}
}
//路由添加全路径
function addFullPath(routes, basePath = '/') {
routes.forEach(route => {
6 years ago
delete route.component
route.fullPath = isExternal(route.path) ? route.path : path.resolve(basePath, route.path)
6 years ago
route.children && addFullPath(route.children, route.fullPath)
6 years ago
})
}
//获取经过权限控制后的路由
function getAuthorizedRoutes({resources, admin}) {
if (admin === true) return finalAuthorityRoutes
6 years ago
if (!resources) return []
6 years ago
filter(finalAuthorityRoutes, i => !needAuth(i) || i.fullPath in resources)
return finalAuthorityRoutes
6 years ago
}
//若没有children且未通过,则删除,若有,当children长度为0时删除
function filter(arr, fun) {
6 years ago
for (let i = arr.length - 1; i >= 0; i--) {
const {children} = arr[i]
if (!children) {
!fun(arr[i]) && arr.splice(i, 1)
6 years ago
continue
}
6 years ago
filter(children, fun)
6 years ago
6 years ago
children.length <= 0 && arr.splice(i, 1)
6 years ago
}
}
//菜单排序
6 years ago
function sort(routes) {
routes.sort((pre, next) => {
6 years ago
pre = getSortValue(pre)
next = getSortValue(next)
if (pre < next) return -1
else if (pre === next) return 0
else return 1
})
routes.forEach(route => {
6 years ago
const {children} = route
if (children && children.length) {
sort(children)
}
})
}
6 years ago
const getSortValue = item => {
const {meta: {sort} = {}} = deepTap(item) || {}
return isEmpty(sort) ? 10000 : sort
}
const deepTap = item => {
const {name, children, meta: {title, hidden, sort} = {}} = item
if (hidden) return null
if (!isEmpty(sort)) return item
if (isEmpty(name, title)) {
//如果是类似首页那样的路由层级
if (children && children.length === 1) {
return deepTap(children[0])
}
}
return null
}
6 years ago
export default {
namespaced: true,
state,
mutations,
actions
}