perf: 修改路由守卫 (#1421)

* perf: 修改路由守卫

* perf: 路由守卫

* perf: 去掉 debug

* perf: 修改img to

* perf: 修改路由

Co-authored-by: ibuler <ibuler@qq.com>
This commit is contained in:
fit2bot
2022-03-09 20:42:36 +08:00
committed by GitHub
parent 148f818349
commit 2b984cb456
8 changed files with 146 additions and 101 deletions

View File

@@ -4,8 +4,7 @@ import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { startup } from '@/utils/startup'
import store from '@/store'
import { getPropView, getRouteViewRequirePerms, hasPermission } from '@/utils/jms'
import Vue from 'vue'
import { isSameView } from '@/utils/jms'
NProgress.configure({
showSpinner: false
@@ -16,7 +15,6 @@ router.beforeEach(async(to, from, next) => {
NProgress.start()
try {
await startup({ to, from, next })
await changeCurrentViewIfNeed({ to, from, next })
next()
} catch (e) {
const msg = 'Start service error: ' + e
@@ -25,9 +23,8 @@ router.beforeEach(async(to, from, next) => {
})
function generateViewRoutesIfChange({ to, from }) {
const fromView = from?.path.split('/')[1]
const toView = to?.path.split('/')[1]
if (fromView !== toView) {
const sameView = isSameView(to, from)
if (!sameView) {
return store.dispatch('permission/generateViewRoutes', { to: to, from: from })
}
}
@@ -41,25 +38,10 @@ function setPageTitle() {
}
}
function changeCurrentViewIfNeed({ to, from, next }) {
if (to.path.slice(0, 5) === from.path.slice(0, 5)) {
return
}
const viewRequirePerms = getRouteViewRequirePerms(to)
const hasPerm = hasPermission(viewRequirePerms)
Vue.$log.debug('Change current view if need: ', viewRequirePerms, hasPerm)
if (hasPerm) {
Vue.$log.debug('Has current view perm')
return
}
const view = getPropView()
next({ name: view })
}
router.afterEach(async(to, from) => {
router.afterEach(async(to, from, next) => {
// finish progress bar
await setPageTitle()
NProgress.done()
await generateViewRoutesIfChange({ to, from })
NProgress.done()
})

View File

@@ -37,6 +37,7 @@
<script>
import { mapGetters } from 'vuex'
import orgUtil from '@/utils/org'
export default {
props: {
isCollapse: {
@@ -63,23 +64,26 @@ export default {
},
methods: {
init() {
const actionObject = {
const orgActions = {
label: this.$t('xpack.Organization.OrganizationList'),
options: [{
id: 'create',
icon: 'fa-plus',
disabled: !this.$hasPerm('orgs.add_organization'),
name: this.$t('xpack.Organization.OrganizationCreate')
}, {
id: 'list',
icon: 'fa-list-ul',
disabled: !this.$hasPerm('orgs.view_organization'),
name: this.$t('xpack.Organization.OrganizationLists')
}]
options: [
{
id: 'create',
icon: 'fa-plus',
disabled: !this.$hasPerm('orgs.add_organization'),
name: this.$t('xpack.Organization.OrganizationCreate')
},
{
id: 'list',
icon: 'fa-list-ul',
disabled: !this.$hasPerm('orgs.view_organization'),
name: this.$t('xpack.Organization.OrganizationLists')
}
]
}
const hasPerms = this.$hasPerm('orgs.view_organization') || this.$hasPerm('xpack.Organization.OrganizationCreate')
const hasPerms = this.$hasPerm('orgs.view_organization | orgs.add_organization')
this.orgOption = [
(hasPerms && actionObject),
(hasPerms && orgActions),
{
label: this.$t('xpack.Organization.AllOrganization'),
options: this.orgs
@@ -100,62 +104,70 @@ export default {
</script>
<style lang="scss" scoped>
@import '~@/styles/element-variables.scss';
.org-select {
padding: 0 10px 0 18px;
line-height: 55px;
background-color: #293846;
color: white;
font-weight: 600;
font-size: 15px;
//border-top: solid 1px rgb(47, 64, 80);
::v-deep .el-input {
input.el-input__inner {
line-height: 55px;
height: 55px;
background: none;
border: none;
}
@import '~@/styles/element-variables.scss';
.org-select {
padding: 0 10px 0 18px;
line-height: 55px;
background-color: #293846;
color: white;
font-weight: 600;
font-size: 15px;
//border-top: solid 1px rgb(47, 64, 80);
::v-deep .el-input {
input.el-input__inner {
line-height: 55px;
height: 55px;
background: none;
border: none;
}
}
.icon {
color: #606266;
cursor: pointer;
}
.icon {
color: #606266;
cursor: pointer;
}
.organization {
height: 35px;
line-height: 35px;
background: #E0E0E0;
border-radius: 19px;
color: #606266;
&:after {
position: absolute;
top: 15%;
left: -16px;
content: '';
width: 1px;
height: 25px;
background-color: rgba(144, 147, 152, .5);
}
.organization {
height: 35px;
line-height: 35px;
background: #E0E0E0;
border-radius: 19px;
& > > > .el-input__prefix {
left: 8px
}
& > > > .el-input--prefix .el-input__inner {
line-height: 35px !important;
height: 35px !important;
}
& > > > .fa-sitemap {
padding-left: 4px;
}
& > > > .el-input__icon {
color: #606266;
&:after {
position: absolute;
top: 15%;
left: -16px;
content: '';
width: 1px;
height: 25px;
background-color: rgba(144,147,152,.5);
}
&>>> .el-input__prefix {
left: 8px
}
&>>> .el-input--prefix .el-input__inner {
line-height: 35px !important;
height: 35px !important;
}
&>>> .fa-sitemap {
padding-left: 4px;
}
&>>> .el-input__icon {
color: #606266;
}
}
.option-group >>> .el-select-group__title {
color: #909399 !important;
padding-left: 15px;
font-size: 12px;
line-height: 30px;
}
}
.option-group > > > .el-select-group__title {
color: #909399 !important;
padding-left: 15px;
font-size: 12px;
line-height: 30px;
}
</style>

View File

@@ -2,10 +2,10 @@
<div class="sidebar-logo-container" :class="{'collapse':collapse}">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img :src="logoSrc" class="sidebar-logo">
<img :src="logoSrc" class="sidebar-logo" alt="logo">
</router-link>
<router-link v-else key="expand" class="sidebar-logo-link" to="/">
<img :src="logoTextSrc" class="sidebar-logo-text">
<img :src="logoTextSrc" class="sidebar-logo-text" alt="logo">
</router-link>
</transition>
</div>

View File

@@ -52,7 +52,6 @@ export default {
'sidebar'
]),
activeMenu() {
console.log('View routes: ', this.currentViewRoute)
const route = this.$route
const { meta, path } = route
// if set path, the sidebar will highlight the path you set

View File

@@ -49,6 +49,16 @@ export const constantRoutes = [
meta: {
icon: 'dashboard',
title: i18n.t('route.Overview')
},
beforeEnter: (to, from, next) => {
console.log('Enter home view')
const preferView = getPermedPreferView()
if (preferView) {
console.log('Go to preferView: ', preferView)
next(`/${preferView}/`)
return false
}
next()
}
}
]
@@ -73,6 +83,7 @@ import workspaceViewRoutes from './workspace'
import ticketsRoutes from './tickets'
import settingsRoutes from './settings'
import profileRoutes from './profile'
import { getPermedPreferView } from '@/utils/jms'
/**
* admin

View File

@@ -182,6 +182,7 @@ const actions = {
if (!matched) {
Vue.$log.debug('Not match path, set default routes', path)
commit('SET_VIEW_ROUTE', constantRoutes[0])
resolve(constantRoutes[0])
return
}
const viewName = matched[1]
@@ -189,12 +190,14 @@ const actions = {
for (const route of state.routes) {
if (route.meta?.view === viewName) {
viewRoute = route
break
}
}
if (viewRoute.meta?.showNavSwitcher) {
localStorage.setItem('PreView', viewName)
}
commit('SET_VIEW_ROUTE', viewRoute)
resolve(viewRoute)
})
},
generateRoutes({ commit, dispatch, rootState }, { to, from }) {
@@ -207,7 +210,6 @@ const actions = {
Vue.$log.debug('All routes: ', routes)
}
commit('SET_ROUTES', { routes })
dispatch('generateViewRoutes', { from, to })
resolve(routes)
})
}

View File

@@ -89,13 +89,7 @@ export function getViewRequirePerms(view) {
return viewRequirePermsMapper[view] || 'super'
}
export function getPropView() {
const preView = localStorage.getItem('PreView')
const preViewRequirePerms = getViewRequirePerms(preView)
const hasPerm = hasPermission(preViewRequirePerms)
if (hasPerm) {
return preView
}
export function getPermedPreferView() {
for (const [view, perms] of Object.entries(viewRequirePermsMapper)) {
const hasPerm = hasPermission(perms)
Vue.$log.debug('Has view perm: ', view, hasPerm)
@@ -103,7 +97,26 @@ export function getPropView() {
return view
}
}
return 'home'
}
export function isSameView(to, from) {
const fromView = from?.path.split('/')[1]
const toView = to?.path.split('/')[1]
return fromView === toView
}
export function getPropView() {
const preView = localStorage.getItem('PreView')
const preViewRequirePerms = getViewRequirePerms(preView)
const hasPerm = hasPermission(preViewRequirePerms)
if (hasPerm) {
return preView
}
const preferView = getPermedPreferView()
if (preferView) {
return preferView
}
return ''
}
export function getApiUrlRequirePerms(url, action) {
@@ -115,3 +128,9 @@ export function getRouteViewRequirePerms(route) {
const viewName = route.path.split('/')[1]
return getViewRequirePerms(viewName)
}
export function hasRouteViewPerm(route) {
const viewName = route.path.split('/')[1]
const perms = getViewRequirePerms(viewName)
return hasPermission(perms)
}

View File

@@ -7,6 +7,7 @@ import 'nprogress/nprogress.css' // progress bar style
import { getTokenFromCookie } from '@/utils/auth'
import orgUtil from '@/utils/org'
import { getCurrentOrg } from '@/api/orgs'
import { getPropView, hasRouteViewPerm, isSameView } from '@/utils/jms'
const whiteList = ['/login', process.env.VUE_APP_LOGIN_PATH] // no redirect whitelist
let initial = false
@@ -84,8 +85,11 @@ export async function generatePageRoutes({ to, from, next }) {
const accessRoutes = await store.dispatch('permission/generateRoutes', { to, from })
// dynamically add accessible routes
Vue.$log.debug('All routes: ', accessRoutes)
router.addRoutes(accessRoutes)
await store.dispatch('permission/generateViewRoutes', { to, from })
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
// Vue.$log.debug('Next to: ', to)
@@ -104,6 +108,21 @@ export async function checkUserFirstLogin({ to, from, next }) {
}
}
export async function changeCurrentViewIfNeed({ to, from, next }) {
if (!to.path || isSameView(to, from)) {
return
}
const hasPerm = hasRouteViewPerm(to)
Vue.$log.debug('Change current view if need: ', hasPerm)
if (hasPerm) {
Vue.$log.debug('Has current view perm')
return
}
const view = getPropView()
Vue.$log.debug('Get prop view and goto: ', view)
next(`/${view}`)
}
export async function startup({ to, from, next }) {
if (initial) {
return true
@@ -116,6 +135,7 @@ export async function startup({ to, from, next }) {
await checkLogin({ to, from, next })
await changeCurrentOrgIfNeed({ to, from, next })
await generatePageRoutes({ to, from, next })
await changeCurrentViewIfNeed({ to, from, next })
await checkUserFirstLogin({ to, from, next })
return true
}