[Update] 修改routes 和 i18n

This commit is contained in:
ibuler
2020-05-13 11:02:36 +08:00
parent 743ed34b54
commit 5000bb6d24
19 changed files with 200 additions and 314 deletions

View File

@@ -8,7 +8,7 @@ export function login(data) {
})
}
export function getInfo(token) {
export function getProfile(token) {
return request({
url: '/api/v1/users/profile/',
method: 'get'

View File

@@ -69,9 +69,6 @@ export default {
return this.moreActionsTitle || this.$t('common.actions.MoreActions')
}
},
mounted() {
this.$log.debug('More action title: ', this.moreActionsTitle)
},
methods: {
handleClick(item) {
const action = this.totalNamedActions[item]

View File

@@ -7,7 +7,7 @@
<script>
import DataForm from '../DataForm'
import FormGroupHeader from '@/components/FormGroupHeader'
import { optionUrlMeta } from '@/api/common'
// import { optionUrlMeta } from '@/api/common'
import rules from '@/components/DataForm/rules'
import { Select2 } from '@/components'
export default {
@@ -49,7 +49,7 @@ export default {
},
methods: {
optionUrlMeta() {
optionUrlMeta(this.url).then(data => {
this.$store.dispatch('common/getUrlMeta', { url: this.url }).then(data => {
this.meta = data.actions[this.method.toUpperCase()] || {}
this.generateColumns()
}).catch(err => {

View File

@@ -4,7 +4,7 @@
<script>
const merge = require('deepmerge')
import { optionUrlMeta } from '@/api/common'
// import { optionUrlMeta } from '@/api/common'
import TagSearch from '@/components/TagSearch'
export default {
name: 'AutoDataSearch',
@@ -28,7 +28,7 @@ export default {
}
},
computed: {
internalConfig() {
iConfig() {
return this.config ? merge(this.defaultConfig, this.config) : this.defaultConfig
}
},
@@ -58,7 +58,7 @@ export default {
},
optionUrlMeta() {
const url = (this.url.indexOf('?') === -1) ? `${this.url}?draw=1&display=1` : `${this.url}&draw=1&display=1`
optionUrlMeta(url).then(data => {
this.$store.dispatch('common/getUrlMeta', { url: url }).then(data => {
this.genericOptions(data.actions['GET'] || {})
})
}

View File

@@ -26,25 +26,39 @@
<script>
import { mapGetters } from 'vuex'
export default {
props: {
isCollapse: {
type: Boolean,
default: () => { return true }
default: () => {
return true
}
}
},
computed: {
...mapGetters([
'currentOrg',
'userAdminOrgList'
])
]),
orgIdMapper() {
const mapper = {}
this.userAdminOrgList.forEach((v) => {
mapper[v.id] = v
})
return mapper
}
},
mounted() {
this.$log.debug('Admin orgs: ', this.userAdminOrgList)
},
methods: {
changeOrg(orgId) {
console.log('Change to org: ', orgId)
this.$store.dispatch('user/setCurrentOrg', {
id: orgId
})
const org = this.orgIdMapper[orgId]
if (!org) {
this.$log.debug('Error: org not found')
}
this.$store.dispatch('users/setCurrentOrg', org)
}
}
}
@@ -56,17 +70,17 @@ export default {
transition: opacity 0s;
}
.org-didi >>> input.el-input__inner {
.org-didi > > > input.el-input__inner {
background: none;
border: none;
color: #8095a8;
}
.org-didi >>> input.el-input__inner::placeholder {
.org-didi > > > input.el-input__inner::placeholder {
opacity: 0.2;
}
.org-didi >>> .el-input__prefix {
.org-didi > > > .el-input__prefix {
line-height: 40px;
/*margin: auto 5px;*/
}

View File

@@ -51,8 +51,7 @@ export default {
},
computed: {
...mapGetters([
'sidebar',
'avatar'
'sidebar'
])
},
methods: {
@@ -60,7 +59,7 @@ export default {
this.$store.dispatch('app/toggleSideBar')
},
async logout() {
await this.$store.dispatch('user/logout')
await this.$store.dispatch('users/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
},
changeLangToZH() {

View File

@@ -15,7 +15,7 @@ NProgress.configure({
showSpinner: false
}) // NProgress Configuration
const whiteList = ['/login'] // no redirect whitelist
const whiteList = ['/login', '/auth/login'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
// start progress bar
@@ -26,60 +26,56 @@ router.beforeEach(async(to, from, next) => {
// determine whether the user has logged in
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({
path: '/'
})
NProgress.done()
} else {
// determine whether the user has obtained his permission roles through getInfo
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if (hasRoles) {
next()
} else {
try {
// get user info
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
const {
role
} = await store.dispatch('user/getInfo')
// generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', [role])
// dynamically add accessible routes
router.addRoutes(accessRoutes)
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
next({
...to,
replace: true
})
} catch (error) {
// remove token and go to login page to re-login
// await store.dispatch('user/resetToken')
// Message.error(error || 'Has Error')
// next(`/login?redirect=${to.path}`)
// NProgress.done()
next()
}
}
}
} else {
if (!hasToken) {
/* has no token*/
// if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
// // in the free login whitelist, go directly
next()
// } else {
// // other pages that do not have permission to access are redirected to the login page.
// next(`/login?redirect=${to.path}`)
// NProgress.done()
// }
return
}
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done()
return
}
// determine whether the user has obtained his permission roles through getProfile
const currentUser = store.getters.currentUser
const hasRoles = currentUser && currentUser.current_org_roles && currentUser.current_org_roles.length > 0
if (hasRoles) {
next()
return
}
try {
// try get user profile
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
const { current_org_roles } = await store.dispatch('users/getProfile')
// generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', current_org_roles)
// dynamically add accessible routes
router.addRoutes(accessRoutes)
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
next({
...to,
replace: true
})
} catch (error) {
// remove token and go to login page to re-login
// await store.dispatch('user/resetToken')
// Message.error(error || 'Has Error')
// next(`/login?redirect=${to.path}`)
// NProgress.done()
next()
}
})

View File

@@ -45,7 +45,10 @@ export const constantRoutes = [
name: '404',
component: () => import('@/views/404'),
hidden: true
},
}
]
export const adminRoutes = [
{
path: '/',
component: Layout,
@@ -141,109 +144,29 @@ export const constantRoutes = [
name: 'CeleryTaskLog',
hidden: true,
meta: { title: 'CeleryTaskLog' }
}
},
{ path: '*', redirect: '/404', hidden: true }
]
/**
* asyncRoutes
* user routes
* the routes that need to be dynamically loaded based on user roles
*/
// 权限路由
export const asyncRoutes = [
// {
// path: '/nested',
// component: Layout,
// redirect: '/nested/menu1',
// name: 'Nested',
// meta: {
// title: 'Nested',
// icon: 'nested'
// },
// children: [
// {
// path: 'menu1',
// component: () => import('@/views/nested/menu1/index'), // Parent router-view
// name: 'Menu1',
// meta: { title: 'Menu1' },
// children: [
// {
// path: 'menu1-1',
// component: () => import('@/views/nested/menu1/menu1-1'),
// name: 'Menu1-1',
// meta: { title: 'Menu1-1' }
// },
// {
// path: 'menu1-2',
// component: () => import('@/views/nested/menu1/menu1-2'),
// name: 'Menu1-2',
// meta: { title: 'Menu1-2' },
// children: [
// {
// path: 'menu1-2-1',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'),
// name: 'Menu1-2-1',
// meta: { title: 'Menu1-2-1' }
// },
// {
// path: 'menu1-2-2',
// component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'),
// name: 'Menu1-2-2',
// meta: { title: 'Menu1-2-2' }
// }
// ]
// },
// {
// path: 'menu1-3',
// component: () => import('@/views/nested/menu1/menu1-3'),
// name: 'Menu1-3',
// meta: { title: 'Menu1-3' }
// }
// ]
// },
// {
// path: 'menu2',
// component: () => import('@/views/nested/menu2/index'),
// meta: { title: 'menu2' }
// }
// ]
// },
// {
// path: '/users',
// component: Layout,
// redirect: '/users/list',
// name: 'Users',
// meta: {
// title: 'Users',
// icon: 'nested'
// },
// children: [
// {
// path: 'user/list',
// component: () => import('@/views/users/UserList.vue'), // Parent router-view
// name: 'UserList',
// meta: { title: 'List' }
// },
// {
// path: 'user/:id',
// component: () => import('@/views/users/UserCreate.vue'), // Parent router-view
// name: 'UserEdit',
// meta: { title: 'Edit' },
// hidden: true
// }
// ]
// },
// {
// path: 'external-link',
// component: Layout,
// children: [
// {
// path: 'https://panjiachen.github.io/vue-element-admin-site/#/',
// meta: { title: 'External Link', icon: 'link' }
// }
// ]
// },
export const userRoutes = [
// 404 page must be placed at the end !!!
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [
{
path: 'dashboard',
name: 'dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: 'Dashboard', icon: 'dashboard' }
}
]
},
{ path: '*', redirect: '/404', hidden: true }
]

View File

@@ -1,15 +1,12 @@
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
roles: state => state.user.roles,
currentOrg: state => state.user.currentOrg,
userAdminOrgList: state => state.user.orgs,
token: state => state.users.token,
currentOrg: state => state.users.currentOrg,
userAdminOrgList: state => state.users.orgs,
currentUser: state => state.users.profile,
permission_routes: state => state.permission.routes,
visitedViews: state => state.tagsView.visitedViews,
cachedViews: state => state.tagsView.cachedViews,
currentUser: state => state.user.user
cachedViews: state => state.tagsView.cachedViews
}
export default getters

View File

@@ -0,0 +1,41 @@
import { optionUrlMeta } from '@/api/common'
const getDefaultState = () => {
return {
metaMap: {}
}
}
const state = getDefaultState()
const mutations = {
setUrlMeta: (state, { url, meta }) => {
state.metaMap[url] = meta
}
}
const actions = {
// get user info
getUrlMeta({ commit, state }, { url }) {
const meta = state.metaMap[url]
if (meta) {
return new Promise((resolve, reject) => {
resolve(meta)
})
}
return new Promise((resolve, reject) => {
optionUrlMeta(url).then(meta => {
commit('setUrlMeta', { url, meta })
resolve(meta)
}).catch(error => {
reject(error)
})
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -1,5 +1,6 @@
import {
asyncRoutes,
adminRoutes,
userRoutes,
constantRoutes
} from '@/router'
@@ -58,9 +59,9 @@ const actions = {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('Admin')) {
accessedRoutes = asyncRoutes || []
accessedRoutes = adminRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
accessedRoutes = filterAsyncRoutes(userRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)

View File

@@ -1,65 +0,0 @@
/* eslint-disable no-unused-vars */
import {
resetRouter
} from '@/router'
const getDefaultState = () => {
return {
tabActive: {
'/abc/': '123'
}
}
}
const state = getDefaultState()
const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState())
}
}
const actions = {
// user login
// login({ commit }, userInfo) {
// const { username, password } = userInfo
// return new Promise((resolve, reject) => {
// login({ username: username.trim(), password: password }).then(response => {
// const { data } = response
// commit('SET_TOKEN', data.token)
// setToken(data.token)
// resolve()
// }).catch(error => {
// reject(error)
// })
// })
// },
setActiveTab({ commit, state }) {
return new Promise(resolve => {
// removeToken() // must remove token first
commit('RESET_STATE')
resolve()
})
},
// remove token
resetToken({
commit
}) {
return new Promise(resolve => {
// removeToken() // must remove token first
commit('RESET_STATE')
resolve()
})
},
setCurrentOrg({ commit }, data) {
commit('SET_CURRENT_ORG', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -1,29 +1,17 @@
/* eslint-disable no-unused-vars */
import {
login,
logout,
getInfo
} from '@/api/user'
import { logout, getProfile } from '@/api/users'
import {
getToken,
getCurrentOrg,
setCurrentOrg,
setToken,
removeToken
setCurrentOrg
} from '@/utils/auth'
import {
resetRouter
} from '@/router'
import { resetRouter } from '@/router'
const getDefaultState = () => {
return {
token: getToken(),
name: '',
avatar: '',
roles: [],
profile: {},
currentOrg: getCurrentOrg(),
orgs: [],
user: {}
orgs: []
}
}
@@ -36,31 +24,21 @@ const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, name) => {
state.name = name
SET_PROFILE: (state, profile) => {
state.profile = profile
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_ORGS: (state, roles) => {
SET_ORGS: (state, orgs) => {
// API BUG FIX
for (let index = 0; index < roles.length; index++) {
if (roles[index].id === 'DEFAULT') {
roles[index].id = ''
for (let index = 0; index < orgs.length; index++) {
if (orgs[index].id === 'DEFAULT') {
orgs[index].id = ''
}
}
state.orgs = roles
state.orgs = orgs
},
SET_CURRENT_ORG(state, z) {
state.currentOrg = z
console.log(z)
setCurrentOrg(z)
},
SET_USER(state, user) {
state.user = user
SET_CURRENT_ORG(state, org) {
state.currentOrg = org
setCurrentOrg(org)
}
}
@@ -80,31 +58,20 @@ const actions = {
// })
// },
// get user info
getInfo({
commit,
state
}) {
// get user Profile
getProfile({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(response => {
getProfile().then(response => {
if (!response) {
reject('Verification failed, please Login again.')
}
const {
role,
name,
avatar_url,
admin_or_audit_orgs
} = response
const rules = [role]
const { admin_or_audit_orgs } = response
// const rules = [role]
// roles must be a non-empty array
if (!rules || rules.length <= 0) {
reject('getInfo: roles must be a non-null array!')
}
commit('SET_USER', response)
commit('SET_ROLES', rules)
commit('SET_NAME', name)
commit('SET_AVATAR', avatar_url)
// if (!rules || rules.length <= 0) {
// reject('getProfile: roles must be a non-null array!')
// }
commit('SET_PROFILE', response)
commit('SET_ORGS', admin_or_audit_orgs)
resolve(response)
}).catch(error => {
@@ -114,10 +81,7 @@ const actions = {
},
// user logout
logout({
commit,
state
}) {
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
// removeToken() // must remove token first
@@ -131,9 +95,7 @@ const actions = {
},
// remove token
resetToken({
commit
}) {
resetToken({ commit }) {
return new Promise(resolve => {
// removeToken() // must remove token first
commit('RESET_STATE')

View File

@@ -60,6 +60,9 @@ service.interceptors.response.use(
return res
},
error => {
if (!error.response) {
return Promise.reject(error)
}
const response = error.response
if (response.status === 401) {
const title = ''

View File

@@ -12,7 +12,6 @@ export default {
name: 'Dashboard',
computed: {
...mapGetters([
'name',
'roles'
])
}

View File

@@ -109,7 +109,7 @@ export default {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$store.dispatch('users/login', this.loginForm).then(() => {
this.$router.push({ path: this.redirect || '/' })
this.loading = false
}).catch(() => {

View File

@@ -3,7 +3,6 @@
</template>
<script>
import i18n from '@/i18n/langs'
import { GenericCreateUpdatePage } from '@/layout/components'
export default {
components: {
@@ -62,9 +61,6 @@ export default {
}
]
}
},
mounted() {
console.log('I18n: ', i18n)
}
}
</script>

View File

@@ -160,7 +160,7 @@ export default {
],
relationConfig: {
icon: 'fa-user',
title: this.$t('users.UserGroups'),
title: this.$t('users.userGroups'),
objectsAjax: {
url: '/api/v1/users/groups/?fields_size=mini&order=name'
},
@@ -217,7 +217,7 @@ export default {
value: this.object.date_expired
},
{
key: this.$t('common.table.createdBy'),
key: this.$t('common.createdBy'),
value: this.object.created_by
},
{

View File

@@ -3,6 +3,7 @@
</template>
<script>
import { mapGetters } from 'vuex'
import { GenericListPage } from '@/layout/components'
export default {
@@ -26,6 +27,16 @@ export default {
groups_display: {
width: '200px',
showOverflowTooltip: true
},
actions: {
hasDelete: this.currentOrgIsDefault(),
extraActions: [
{
title: 'Remove',
type: 'warning',
has: !this.currentOrgIsDefault()
}
]
}
}
},
@@ -48,6 +59,18 @@ export default {
]
}
}
},
computed: {
...mapGetters([
'currentOrg'
])
},
methods: {
currentOrgIsDefault() {
console.log(this.currentOrg)
return false
// return this.currentOrg.id === 'DEFAULT'
}
}
}
</script>