diff --git a/src/components/ParentView/index.vue b/src/components/ParentView/index.vue
new file mode 100644
index 0000000..621cb5a
--- /dev/null
+++ b/src/components/ParentView/index.vue
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/src/components/Hello.vue b/src/layout/index.vue
similarity index 100%
rename from src/components/Hello.vue
rename to src/layout/index.vue
diff --git a/src/main.js b/src/main.js
index e4bf66f..064b8be 100644
--- a/src/main.js
+++ b/src/main.js
@@ -13,7 +13,7 @@ import 'element-ui/lib/theme-chalk/index.css'
import VueHighlightJS from 'vue-highlightjs'
import 'highlight.js/styles/atom-one-dark.css'
// 加载路由
-import './router/index'
+import './router/routers'
//加载权限指令
import checkPer from '@/utils/permission'
@@ -21,8 +21,6 @@ import checkPer from '@/utils/permission'
-//加载路由
-Vue.use(router)
// 加载代码高亮
Vue.use(VueHighlightJS)
// 加载elementui
diff --git a/src/router/index.js b/src/router/index.js
index 1398245..ad73c34 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -7,9 +7,12 @@ import 'nprogress/nprogress.css'
import {
getToken
} from '@/utils/auth'
-// import {
-// filterAsyncRouter
-// } from '@/store/modules/permission'
+import {
+ filterAsyncRouter
+} from '@/store/modules/permission'
+import {
+ buildMenus
+} from '@/api/system/menu'
@@ -22,18 +25,93 @@ const whiteList = ['/login']
//路由守卫,路由跳转前执行钩子函数
//to:目标路由对象
-//from:即将要离开的路由对象
-//next:执行效果依赖
+//from:当前路由
+//next:放行或重载
router.beforeEach((to, from, next) => {
- //如果路由标题设置则显示配置标题和目标菜单标题
+ // 如果路由标题设置则显示配置标题和目标菜单标题
if (to.meta.title) {
document.title = to.meta.title + '-' + Config.title
}
+ //加载效果
NProgress.start()
- next(`/login?redirect=${to.fullPath}`)
+ //如果已登录过且要跳转的页面是登录页,执行下一次路由守卫
+ if (getToken()) {
+ if (to.path === '/login') {
+ next({
+ path: '/'
+ })
+ NProgress.done()
+ } else {
+ //判断当前用户是否已拉取完用户信息
+ if (store.getters.roles.length === 0) {
+ //拉取user_info
+ store.dispatch('GetInfo').then(() => {
+ //加载动态路由,拉取菜单
+ loadMenus(next, to)
+ }).catch(() => {
+ store.dispatch('LogOut').then(() => {
+ //重新实例化路由对象 避免bug
+ location.reload()
+ })
+ })
+ } else if (store.getters.loadMenus) {
+ store.dispatch('updateLoadMenus')
+ loadMenus(next, to)
+ } else {
+ next()
+ }
+ }
+ } else {
+ //hsa no token
+ //在免登录白名单,直接进入
+ if (whiteList.indexOf(to.path) !== -1) {
+ next()
+ } else {
+ //否则全部重定向到登录页面
+ next(`/loginredirect=${to.fullPath}`)
+ NProgress.done()
+ }
+ }
NProgress.done()
})
-router.afterEach(()=>{
+export const loadMenus = (next, to) => {
+
+ buildMenus().then(res => {
+ const sdata = JSON.parse(JSON.stringify(res))
+ const rdata = JSON.parse(JSON.stringify(res))
+ const sidebarRoutes = filterAsyncRouter()
+ })
+
+ rewriteRoutes.push({
+ path: '*',
+ redirect: '/404',
+ hidden: true
+ })
+
+ //存储路由
+ store.dispatch('GenerateRoutes', rewriteRoutes).then(() => {
+ /*
+ * 在addRoutes()之后第一次访问被添加的路由会白屏,
+ * 这是因为刚刚addRoutes()就立刻访问被添加的路由,
+ * 然而此时addRoutes()没有执行结束,
+ * 因而找不到刚刚被添加的路由导致白屏
+ */
+ router.addRoutes(rewriteRoutes)
+ /*
+ * 确保addRoutes()时动态添加的路由已经被完全加载上去
+ * replace: true只是一个设置信息,
+ * 告诉VUE本次操作后,
+ * 不能通过浏览器后退按钮,返回前一个路由
+ */
+ next({
+ ...to,
+ replace: true
+ })
+ })
+ store.dispatch('SetSidebarRouters', sidebarRoutes)
+}
+
+router.afterEach(() => {
NProgress.done()
})
diff --git a/src/router/routers.js b/src/router/routers.js
index 5f73203..7a685cc 100644
--- a/src/router/routers.js
+++ b/src/router/routers.js
@@ -1,5 +1,6 @@
import Vue from 'vue'
import Router from 'vue-router'
+import Config from '@/settings'
//加载路由
@@ -28,8 +29,6 @@ export default new Router({
//修改路由,取消hash的注释改变部署模式
//mode:'hash',
mode: 'history',
- scrollBehavior: () => ({
- y: 0
- }),
+ scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap
})
diff --git a/src/settings.js b/src/settings.js
index be219cc..6724201 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -16,4 +16,10 @@ module.exports = {
//请求超时时间,毫秒(默认2分钟)
timeout: 1200000,
+ //是否显示设置底部信息
+ showFooter: true,
+
+ //底部文字,支持html语法
+ footerTxt:'© 2021 阅行客后台管理系统'
+
}
diff --git a/src/store/modules/api.js b/src/store/modules/api.js
new file mode 100644
index 0000000..02788ef
--- /dev/null
+++ b/src/store/modules/api.js
@@ -0,0 +1,28 @@
+//适配Nginx反向代理
+const baseUrl = process.env.VUE_APP_BASE_API === '/' ? '' : process.env.VUE_APP_BASE_API
+
+//适配API路径
+const api = {
+ state: {
+
+ //部署包上传
+ //deployUploadApi: baseUrl + '/api/deploy/upload',
+
+ //图片上传
+ imagesUplaodApi: baseUrl + '/api/localStorage/pictures',
+
+ //上传图像
+ updateAvatarApi: baseUrl + '/api/users/updateAvatar',
+
+ //文件上传
+ fileUploadApi: baseUrl + '/api/localStorage',
+
+ // swagger
+ swaggerApi: baseUrl + '/swagger-ui.html',
+
+ //基础url
+ baseApi: baseUrl
+ }
+}
+
+export default api
diff --git a/src/store/modules/permission.js b/src/store/modules/permission.js
new file mode 100644
index 0000000..063253c
--- /dev/null
+++ b/src/store/modules/permission.js
@@ -0,0 +1,86 @@
+import { constantRouterMap } from "@/router/routers";
+import Layout from '@/layout/index'
+import ParentView from '@/components/ParentView'
+
+const permission = {
+ //存放状态
+ state: {
+ routers: constantRouterMap,
+ addRouters: [],
+ sidebarRouters: []
+ },
+ //同步更改状态
+ mutations: {
+ SET_ROUTERS: (state, routers) => {
+ state.addRouters = routers
+ state.routers = constantRouterMap.concat(routers)
+ },
+ SET_SIDEBAR_ROUTERS: (state, routers) => {
+ state.sidebarRouters = constantRouterMap.concat(routers)
+ }
+ },
+ //发送异步请求拿到数据
+ actions: {
+ GenerateRoutes({
+ commit
+ }, asyncRouter) {
+ commit('SET_ROUTERS', asyncRouter)
+ },
+ SetSidebarRouters({
+ commit
+ }, sidebarRouter) {
+ commit('SET_SIDEBAR_ROUTERS', sidebarRouter)
+ }
+ }
+
+}
+
+//遍历后台传来的路由字符串,转换为组件对象
+export const filterAsyncRouter = (routers, isRewrite = false) => {
+ return routers.filter(router => {
+ if (isRewrite && router.children) {
+ router.children = filterChildren(router.children)
+ }
+ if (router.component) {
+ if (router.component === 'Layout') { // Layout组件特殊处理
+ router.component = Layout
+ } else if (router.component === 'ParentView') {
+ router.component = ParentView
+ } else {
+ const component = router.component
+ router.component = loadView(component)
+ }
+ }
+ if (router.children && router.children.length) {
+ router.children = filterAsyncRouter(router.children, router, isRewrite)
+ }
+ return true
+ })
+}
+
+function filterChildren(childrenMap) {
+ var children = []
+ childrenMap.forEach((el, index) => {
+ if (el.children && el.children.length) {
+ if (el.component === 'ParentView') {
+ el.children.forEach(c => {
+ c.path = el.path + '/' + c.path
+ if (c.children && c.children.length) {
+ children = children.concat(filterChildren(c.children, c))
+ return
+ }
+ children.push(c)
+ })
+ return
+ }
+ }
+ children = children.concat(el)
+ })
+ return children
+}
+
+export const loadView = (view) => {
+ return (resolve) => require([`@/views/${view}`], resolve)
+}
+
+export default permission
diff --git a/src/utils/request.js b/src/utils/request.js
index 4fab665..e4df359 100644
--- a/src/utils/request.js
+++ b/src/utils/request.js
@@ -7,7 +7,7 @@ import Config from '@/settings'
import Cookies from "js-cookie"
-//创建axios 实例
+//二次封装axios,创建axios 实例
const service = axios.create({
//api 的 base_url在.env.development有配置
baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/',
diff --git a/src/views/login.vue b/src/views/login.vue
new file mode 100644
index 0000000..8d6593f
--- /dev/null
+++ b/src/views/login.vue
@@ -0,0 +1,240 @@
+
+
+
+
+ 阅行集成后台管理
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 记住我
+
+
+
+ 登 录
+ 登 录 中...
+
+
+
+
+
+
+
+
+
+
+