refactor(index): 完善登录、路由、请求库等功能,添加用户路由

duizhaopin_ui
duan 3 years ago
parent 198b5516e8
commit c915903832

@ -17,7 +17,7 @@
:collapse-transition="false" :collapse-transition="false"
mode="vertical" mode="vertical"
> >
<sidebar-item v-for="route in routes" :key="route.path" :item="route" :base-path="route.path" /> <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />
</el-menu> </el-menu>
</el-scrollbar> </el-scrollbar>
</div> </div>
@ -38,11 +38,12 @@ export default {
}, },
computed: { computed: {
...mapGetters([ ...mapGetters([
'permission_routes',
'sidebar' 'sidebar'
]), ]),
routes() { // routes() {
return this.$router.options.routes // return this.$router.options.routes
}, // },
activeMenu() { activeMenu() {
const route = this.$route const route = this.$route
const { meta, path } = route const { meta, path } = route

@ -1,6 +1,6 @@
import router from './router' import router, { asyncRoutes } from './router'
import store from './store' import store from './store'
import { Message } from 'element-ui' // import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style import 'nprogress/nprogress.css' // progress bar style
import getPageTitle from '@/utils/get-page-title' import getPageTitle from '@/utils/get-page-title'
@ -25,23 +25,30 @@ router.beforeEach(async(to, from, next) => {
next({ path: '/' }) next({ path: '/' })
NProgress.done() NProgress.done()
} else { } else {
const hasGetUserInfo = store.getters.name if (to.name) {
if (hasGetUserInfo) {
next() next()
} else { } else {
try { store.commit('permission/SET_ROUTES', asyncRoutes)
// get user info router.addRoutes(asyncRoutes)
// await store.dispatch('user/getInfo') next({ ...to, replace: true })
next()
} 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()
}
} }
// const hasGetUserInfo = store.getters.name
// if (hasGetUserInfo) {
// next()
// } else {
// try {
// // get user info
// // await store.dispatch('user/getInfo')
//
// next()
// } 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()
// }
// }
} }
} else { } else {
/* has no token*/ /* has no token*/

@ -4,7 +4,8 @@ import Router from 'vue-router'
Vue.use(Router) Vue.use(Router)
/* Layout */ /* Layout */
import Layout from '@/layout' import reagentRouter from './modules/reagent'
import userRouter from '@/router/modules/user'
/** /**
* Note: sub-menu only appear when route children.length >= 1 * Note: sub-menu only appear when route children.length >= 1
@ -46,199 +47,16 @@ export const constantRoutes = [
path: '/', path: '/',
redirect: '/home' redirect: '/home'
}, },
{ {
path: '/404', path: '/404',
component: () => import('@/views/404'), component: () => import('@/views/404'),
hidden: true hidden: true
},
{
path: '/reagent',
component: Layout,
redirect: '/reagent/mainoverview/index'
},
{
path: '/reagent/mainoverview',
component: Layout,
children: [
{
path: 'index',
name: 'MainOverview',
meta: { title: '主预览', icon: '主概览' },
component: () => import('@/views/reagent/mainoverview/index')
} }
] ]
},
{ export const asyncRoutes = [
path: '/reagent/report', ...reagentRouter,
component: Layout, ...userRouter,
children: [
{
path: 'index',
name: 'Report',
component: () => import('@/views/reagent/report/index'),
meta: { title: '报告统计', icon: '报表统计' }
},
{
path: 'storeinfo',
name: 'StoreInfo',
component: () => import('@/views/reagent/report/storeinfo/index'),
hidden: true,
meta: { title: '库存信息总览', icon: '报表统计' }
},
{
path: 'reagentinfo',
name: 'ReagentInfo',
component: () => import('@/views/reagent/report/reagentinfo/index'),
hidden: true,
meta: { title: '试剂信息详情', icon: '报表统计' }
},
{
path: 'warehousinginfo',
name: 'WarehousingInfo',
component: () => import('@/views/reagent/report/warehousinginfo/index'),
hidden: true,
meta: { title: '入库信息查询', icon: '报表统计' }
},
{
path: 'inventoryconsuminfo',
name: 'InventoryConsumInfo',
component: () => import('@/views/reagent/report/inventoryconsum/index'),
hidden: true,
meta: { title: '库存消耗', icon: '报表统计' }
},
{
path: 'reagentconsuminfo',
name: 'ReagentConsumInfo',
component: () => import('@/views/reagent/report/reagentconsum/index'),
hidden: true,
meta: { title: '试剂消耗', icon: '报表统计' }
},
{
path: 'userconsuminfo',
name: 'UserConsumInfo',
component: () => import('@/views/reagent/report/userconsum/index'),
hidden: true,
meta: { title: '人员用量消耗', icon: '报表统计' }
},
{
path: 'usefrequencyinfo',
name: 'UseFrequencyInfo',
component: () => import('@/views/reagent/report/usefrequency/index'),
hidden: true,
meta: { title: '使用频率', icon: '报表统计' }
},
{
path: 'recordinfo/:t',
name: 'RecordInfo',
component: () => import('@/views/reagent/report/record/index'),
hidden: true,
meta: { title: '记录', icon: '报表统计' }
}
]
},
{
path: '/reagent/warehousing',
component: Layout,
children: [
{
path: 'index',
name: 'Warehousing',
component: () => import('@/views/reagent/warehousing/index'),
meta: { title: '试剂入库', icon: '试剂入库' }
}
]
},
{
path: '/reagent/receiving',
component: Layout,
children: [
{
path: 'index',
name: 'Receiving',
component: () => import('@/views/reagent/receivingandreturn/index'),
meta: { title: '试剂领用', icon: '试剂领用' }
}
]
},
{
path: '/reagent/sendback',
component: Layout,
children: [
{
path: 'index',
name: 'SendBack',
component: () => import('@/views/reagent/receivingandreturn/index'),
meta: { title: '试剂归还', icon: '试剂归还' }
}
]
},
{
path: '/reagent/weighing',
component: Layout,
children: [
{
path: 'index',
name: 'weighing',
component: () => import('@/views/reagent/weighing/index'),
meta: { title: '试剂称重', icon: '试剂称重' }
}
]
},
{
path: '/reagent/inventory',
component: Layout,
children: [
{
path: 'index',
name: 'Inventory',
component: () => import('@/views/reagent/inventory/index'),
meta: { title: '试剂盘点', icon: '库存盘点' }
}
]
},
{
path: '/reagent/database',
component: Layout,
children: [
{
path: 'index',
name: 'Database',
component: () => import('@/views/reagent/database/index'),
meta: { title: '化学品数据库', icon: '化学品数据库' }
}
]
},
{
path: '/reagent/management',
component: Layout,
children: [
{
path: 'index',
name: 'Management',
component: () => import('@/views/reagent/management/index'),
meta: { title: '试剂管理', icon: '试剂管理' }
}
]
},
{
path: '/reagent/buy',
component: Layout,
children: [
{
path: 'index',
name: 'Buy',
component: () => import('@/views/reagent/buy/index'),
meta: { title: '请购', icon: '请购' }
}
]
},
{
path: '/gotohome',
redirect: '/home',
meta: { title: '返回主页', icon: 'el-icon-arrow-left' }
},
// 404 page must be placed at the end !!! // 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true } { path: '*', redirect: '/404', hidden: true }
] ]

@ -0,0 +1,202 @@
import Layout from '@/layout'
const reagentRouter = [
{
path: '/reagent',
hidden: true,
redirect: '/reagent/mainoverview/index'
},
{
path: '/reagent/mainoverview',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'MainOverview',
meta: { title: '主预览', icon: '主概览', class: 'reagent' },
component: () => import('@/views/reagent/mainoverview/index')
}
]
},
{
path: '/reagent/report',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'Report',
component: () => import('@/views/reagent/report/index'),
meta: { title: '报告统计', icon: '报表统计', class: 'reagent' }
},
{
path: 'storeinfo',
name: 'StoreInfo',
component: () => import('@/views/reagent/report/storeinfo/index'),
hidden: true,
meta: { title: '库存信息总览', icon: '报表统计', class: 'reagent' }
},
{
path: 'reagentinfo',
name: 'ReagentInfo',
component: () => import('@/views/reagent/report/reagentinfo/index'),
hidden: true,
meta: { title: '试剂信息详情', icon: '报表统计', class: 'reagent' }
},
{
path: 'warehousinginfo',
name: 'WarehousingInfo',
component: () => import('@/views/reagent/report/warehousinginfo/index'),
hidden: true,
meta: { title: '入库信息查询', icon: '报表统计', class: 'reagent' }
},
{
path: 'inventoryconsuminfo',
name: 'InventoryConsumInfo',
component: () => import('@/views/reagent/report/inventoryconsum/index'),
hidden: true,
meta: { title: '库存消耗', icon: '报表统计', class: 'reagent' }
},
{
path: 'reagentconsuminfo',
name: 'ReagentConsumInfo',
component: () => import('@/views/reagent/report/reagentconsum/index'),
hidden: true,
meta: { title: '试剂消耗', icon: '报表统计', class: 'reagent' }
},
{
path: 'userconsuminfo',
name: 'UserConsumInfo',
component: () => import('@/views/reagent/report/userconsum/index'),
hidden: true,
meta: { title: '人员用量消耗', icon: '报表统计', class: 'reagent' }
},
{
path: 'usefrequencyinfo',
name: 'UseFrequencyInfo',
component: () => import('@/views/reagent/report/usefrequency/index'),
hidden: true,
meta: { title: '使用频率', icon: '报表统计', class: 'reagent' }
},
{
path: 'recordinfo/:t',
name: 'RecordInfo',
component: () => import('@/views/reagent/report/record/index'),
hidden: true,
meta: { title: '记录', icon: '报表统计', class: 'reagent' }
}
]
},
{
path: '/reagent/warehousing',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'Warehousing',
component: () => import('@/views/reagent/warehousing/index'),
meta: { title: '试剂入库', icon: '试剂入库', class: 'reagent' }
}
]
},
{
path: '/reagent/receiving',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'Receiving',
component: () => import('@/views/reagent/receivingandreturn/index'),
meta: { title: '试剂领用', icon: '试剂领用', class: 'reagent' }
}
]
},
{
path: '/reagent/sendback',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'SendBack',
component: () => import('@/views/reagent/receivingandreturn/index'),
meta: { title: '试剂归还', icon: '试剂归还', class: 'reagent' }
}
]
},
{
path: '/reagent/weighing',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'weighing',
component: () => import('@/views/reagent/weighing/index'),
meta: { title: '试剂称重', icon: '试剂称重', class: 'reagent' }
}
]
},
{
path: '/reagent/inventory',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'Inventory',
component: () => import('@/views/reagent/inventory/index'),
meta: { title: '试剂盘点', icon: '库存盘点', class: 'reagent' }
}
]
},
{
path: '/reagent/database',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'Database',
component: () => import('@/views/reagent/database/index'),
meta: { title: '化学品数据库', icon: '化学品数据库', class: 'reagent' }
}
]
},
{
path: '/reagent/management',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'Management',
component: () => import('@/views/reagent/management/index'),
meta: { title: '试剂管理', icon: '试剂管理', class: 'reagent' }
}
]
},
{
path: '/reagent/buy',
component: Layout,
meta: { class: 'reagent' },
children: [
{
path: 'index',
name: 'Buy',
component: () => import('@/views/reagent/buy/index'),
meta: { title: '请购', icon: '请购', class: 'reagent' }
}
]
},
{
path: '/gotohome',
redirect: '/home',
meta: { title: '返回主页', icon: 'el-icon-arrow-left', class: 'reagent' }
}
]
export default reagentRouter

@ -0,0 +1,40 @@
// import Layout from '@/layout'
import Layout from '@/layout'
const userRouter = [
{
path: '/user',
redirect: '/user/info/index',
hidden: true,
meta: { class: 'user' }
},
{
path: '/user/info',
component: Layout,
meta: { class: 'user' },
children: [
{
path: 'index',
component: () => import('@/views/user/index'),
name: 'UserInfo',
meta: { title: '用户信息', icon: 'lock', class: 'user' }
}
]
},
{
path: '/user/role',
component: Layout,
meta: { class: 'user' },
children: [
{
path: 'index',
component: () => import('@/views/user/role/index'),
name: 'Role',
meta: { title: '角色信息', icon: 'lock', class: 'user' }
}
]
}
]
export default userRouter

@ -3,6 +3,7 @@ const getters = {
device: state => state.app.device, device: state => state.app.device,
token: state => state.user.token, token: state => state.user.token,
avatar: state => state.user.avatar, avatar: state => state.user.avatar,
name: state => state.user.name name: state => state.user.name,
permission_routes: state => state.permission.routes
} }
export default getters export default getters

@ -4,6 +4,7 @@ import getters from './getters'
import app from './modules/app' import app from './modules/app'
import settings from './modules/settings' import settings from './modules/settings'
import user from './modules/user' import user from './modules/user'
import permission from './modules/permission'
import createPersistedState from 'vuex-persistedstate' import createPersistedState from 'vuex-persistedstate'
Vue.use(Vuex) Vue.use(Vuex)
@ -11,7 +12,8 @@ const store = new Vuex.Store({
modules: { modules: {
app, app,
settings, settings,
user user,
permission
}, },
getters, getters,
plugins: [createPersistedState()] plugins: [createPersistedState()]

@ -0,0 +1,69 @@
import { asyncRoutes, constantRoutes } from '@/router'
/**
* Use meta.role to determine if the current user has permission
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
}
/**
* Filter asynchronous routing tables by recursion
* @param routes asyncRoutes
* @param roles
*/
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
const state = {
routes: [],
addRoutes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

@ -18,7 +18,7 @@ service.interceptors.request.use(
// let each request carry token // let each request carry token
// ['X-Token'] is a custom headers key // ['X-Token'] is a custom headers key
// please modify it according to the actual situation // please modify it according to the actual situation
config.headers['Authorization'] = store.getters.token config.headers['Authorization'] = 'Bearer ' + store.getters.token
} }
return config return config
}, },
@ -53,11 +53,20 @@ service.interceptors.response.use(
}) })
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) { if (res.status === 401) {
// to re-login // to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { // MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login', // confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel', // cancelButtonText: 'Cancel',
// type: 'warning'
// }).then(() => {
// store.dispatch('user/resetToken').then(() => {
// location.reload()
// })
// })
MessageBox.confirm('登录超时请重新登录', '返回登录', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
store.dispatch('user/resetToken').then(() => { store.dispatch('user/resetToken').then(() => {

@ -72,6 +72,7 @@
// import { validUsername } from '@/utils/validate' // import { validUsername } from '@/utils/validate'
import stringify from '@/utils/stringify' import stringify from '@/utils/stringify'
import { login } from '@/api/user/user' import { login } from '@/api/user/user'
import { asyncRoutes } from '@/router'
export default { export default {
name: 'Login', name: 'Login',
data() { data() {
@ -131,8 +132,9 @@ export default {
this.loading = true this.loading = true
login(stringify(this.loginForm)).then(res => { login(stringify(this.loginForm)).then(res => {
this.$store.commit('user/SET_TOKEN', res.data.token) this.$store.commit('user/SET_TOKEN', res.data.token)
console.log(this.$store.getters.token) this.$store.commit('permission/SET_ROUTES', asyncRoutes)
this.$router.push('/home') this.$router.addRoutes(asyncRoutes)
this.$router.replace('/home')
}).finally( }).finally(
() => { () => {
this.loading = false this.loading = false

@ -0,0 +1,13 @@
<template>
<h1>用户根目录</h1>
</template>
<script>
export default {
name: 'User'
}
</script>
<style scoped>
</style>

@ -0,0 +1,13 @@
<template>
<h1>角色信息</h1>
</template>
<script>
export default {
name: 'Role'
}
</script>
<style scoped>
</style>
Loading…
Cancel
Save