持续修整内容

This commit is contained in:
zxx 2022-10-14 14:39:39 +08:00
parent d19ce89143
commit b5bf802ab2
23 changed files with 356 additions and 176 deletions

5
.env
View File

@ -2,8 +2,11 @@ VUE_APP_PUBLIC_PATH=/
VUE_APP_NAME=Admin
VUE_APP_ROUTES_KEY=admin.routes
VUE_APP_PERMISSIONS_KEY=admin.permissions
VUE_APP_UID_KEY=admin.uid
VUE_APP_USER_KEY=admin.user
VUE_APP_SETTING_KEY=admin.setting
VUE_APP_USER_SETTINGS_KEY=admin.user.settings
VUE_APP_TBAS_KEY=admin.tabs
VUE_APP_TBAS_TITLES_KEY=admin.tabs.titles
VUE_APP_API_BASE_URL=http://192.168.31.91:19000
# VUE_APP_API_BASE_URL=http://192.168.31.91:19000
VUE_APP_API_BASE_URL=http://192.168.52.166:30000

View File

@ -1 +1,2 @@
VUE_APP_API_BASE_URL=http://192.168.31.91:19000
VUE_APP_API_BASE_URL=http://192.168.52.166:30000

View File

@ -1,19 +1,27 @@
<template>
<a-layout :class="['admin-layout', 'beauty-scroll']">
<drawer v-if="isMobile" v-model="drawerOpen">
<side-menu :theme="theme.mode" :menuData="menuData" :collapsed="false" :collapsible="false" @menuSelect="onMenuSelect"/>
<side-menu :theme="theme.mode" :menuData="menuData" :collapsed="false" :collapsible="false"
@menuSelect="onMenuSelect" />
</drawer>
<side-menu :class="[fixedSideBar ? 'fixed-side' : '']" :theme="theme.mode" v-else-if="layout === 'side' || layout === 'mix'" :menuData="sideMenuData" :collapsed="collapsed" :collapsible="true" />
<div v-if="fixedSideBar && !isMobile" :style="`width: ${sideMenuWidth}; min-width: ${sideMenuWidth};max-width: ${sideMenuWidth};`" class="virtual-side"></div>
<side-menu :class="[fixedSideBar ? 'fixed-side' : '']" :theme="theme.mode"
v-else-if="layout === 'side' || layout === 'mix'" :menuData="sideMenuData" :collapsed="collapsed"
:collapsible="true" />
<div v-if="fixedSideBar && !isMobile"
:style="`width: ${sideMenuWidth}; min-width: ${sideMenuWidth};max-width: ${sideMenuWidth};`" class="virtual-side">
</div>
<drawer v-if="!hideSetting" v-model="showSetting" placement="right">
<div class="setting" slot="handler">
<a-icon :type="showSetting ? 'close' : 'setting'"/>
<a-icon :type="showSetting ? 'close' : 'setting'" />
</div>
<setting />
</drawer>
<a-layout class="admin-layout-main beauty-scroll">
<admin-header :class="[{'fixed-tabs': fixedTabs, 'fixed-header': fixedHeader, 'multi-page': multiPage}]" :style="headerStyle" :menuData="headMenuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse"/>
<a-layout-header :class="['virtual-header', {'fixed-tabs' : fixedTabs, 'fixed-header': fixedHeader, 'multi-page': multiPage}]" v-show="fixedHeader"></a-layout-header>
<admin-header :class="[{'fixed-tabs': fixedTabs, 'fixed-header': fixedHeader, 'multi-page': multiPage}]"
:style="headerStyle" :menuData="headMenuData" :collapsed="collapsed" @toggleCollapse="toggleCollapse" />
<a-layout-header
:class="['virtual-header', {'fixed-tabs' : fixedTabs, 'fixed-header': fixedHeader, 'multi-page': multiPage}]"
v-show="fixedHeader"></a-layout-header>
<a-layout-content class="admin-layout-content" :style="`min-height: ${minHeight}px;`">
<div style="position: relative">
<slot></slot>
@ -32,17 +40,15 @@ import PageFooter from './footer/PageFooter' // 加载页脚组件
import Drawer from '../components/tool/Drawer' //
import SideMenu from '../components/menu/SideMenu' //
import Setting from '../components/setting/Setting' //
import {mapState, mapMutations, mapGetters} from 'vuex' // vuex
import { mapState, mapMutations, mapGetters } from 'vuex' // vuex
// const minHeight = window.innerHeight - 64 - 122
export default {
name: 'AdminLayout', //
components: {Setting, SideMenu, Drawer, PageFooter, AdminHeader}, //
data () {
components: { Setting, SideMenu, Drawer, PageFooter, AdminHeader }, //
data() {
return {
minHeight: window.innerHeight - 64 - 122, //
collapsed: false, //
@ -63,17 +69,17 @@ export default {
this.setActivated(this.$route) //
},
isMobile(val) { //
if(!val) {
if (!val) {
this.drawerOpen = false
}
}
},
computed: {
...mapState('setting', ['isMobile', 'theme', 'layout', 'footerLinks', 'copyright', 'fixedHeader', 'fixedSideBar',
'fixedTabs', 'hideSetting', 'multiPage']),
// vuex
...mapGetters('setting', ['firstMenu', 'subMenu', 'menuData']),
// vuex
'fixedTabs', 'hideSetting', 'multiPage']),
// vuex
...mapGetters('setting', ['firstMenu', 'subMenu', 'menuData']),
// vuex
sideMenuWidth() { //
return this.collapsed ? '80px' : '256px'
},
@ -83,27 +89,27 @@ export default {
return `width: ${width}; position: ${position};` //
},
headMenuData() { //
const {layout, menuData, firstMenu} = this //
const { layout, menuData, firstMenu } = this //
return layout === 'mix' ? firstMenu : menuData //
},
sideMenuData() { //
const {layout, menuData, subMenu} = this //
const { layout, menuData, subMenu } = this //
return layout === 'mix' ? subMenu : menuData //
}
},
methods: {
...mapMutations('setting', ['correctPageMinHeight', 'setActivatedFirst']), //
toggleCollapse () { //
toggleCollapse() { //
this.collapsed = !this.collapsed //
},
onMenuSelect () { //
onMenuSelect() { //
this.toggleCollapse() //
},
setActivated(route) { //
if (this.layout === 'mix') { //
let matched = route.matched //
matched = matched.slice(0, matched.length - 1) //
const {firstMenu} = this //
const { firstMenu } = this //
for (let menu of firstMenu) { //
if (matched.findIndex(item => item.path === menu.fullPath) !== -1) { //
this.setActivatedFirst(menu.fullPath) //
@ -116,6 +122,7 @@ export default {
created() { //
this.correctPageMinHeight(this.minHeight - 24) //
this.setActivated(this.$route) //
},
beforeDestroy() { //
this.correctPageMinHeight(-this.minHeight + 24) //
@ -124,50 +131,57 @@ export default {
</script>
<style lang="less" scoped>
.admin-layout{
.side-menu{
&.fixed-side{
position: fixed;
height: 100vh;
left: 0;
top: 0;
}
.admin-layout {
.side-menu {
&.fixed-side {
position: fixed;
height: 100vh;
left: 0;
top: 0;
}
.virtual-side{
transition: all 0.2s;
}
.virtual-side {
transition: all 0.2s;
}
.virtual-header {
transition: all 0.2s;
opacity: 0;
&.fixed-tabs.multi-page:not(.fixed-header) {
height: 0;
}
.virtual-header{
}
.admin-layout-main {
.admin-header {
top: 0;
right: 0;
overflow: hidden;
transition: all 0.2s;
opacity: 0;
&.fixed-tabs.multi-page:not(.fixed-header){
&.fixed-tabs.multi-page:not(.fixed-header) {
height: 0;
}
}
.admin-layout-main{
.admin-header{
top: 0;
right: 0;
overflow: hidden;
transition: all 0.2s;
&.fixed-tabs.multi-page:not(.fixed-header){
height: 0;
}
}
}
.admin-layout-content{
padding: 24px 24px 0;
/*overflow-x: hidden;*/
/*min-height: calc(100vh - 64px - 122px);*/
}
.setting{
background-color: @primary-color;
color: @base-bg-color;
border-radius: 5px 0 0 5px;
line-height: 40px;
font-size: 22px;
width: 40px;
height: 40px;
box-shadow: -2px 0 8px @shadow-color;
}
}
.admin-layout-content {
padding: 24px 24px 0;
/*overflow-x: hidden;*/
/*min-height: calc(100vh - 64px - 122px);*/
}
.setting {
background-color: @primary-color;
color: @base-bg-color;
border-radius: 5px 0 0 5px;
line-height: 40px;
font-size: 22px;
width: 40px;
height: 40px;
box-shadow: -2px 0 8px @shadow-color;
}
}
</style>

View File

@ -86,6 +86,8 @@ export default {
marginCorrect() { //
return this.multiPage ? 24 : 0 //
}
},
methods: {
...mapMutations('setting', ['correctPageMinHeight']), // vuex

View File

@ -14,6 +14,7 @@ import PageLayout from './PageLayout'
import PageToggleTransition from '../components/transition/PageToggleTransition';
import {mapState} from 'vuex'
export default {
name: 'PageView',
components: {PageToggleTransition, PageLayout},

View File

@ -82,10 +82,15 @@
<script>
import CommonLayout from '@/layouts/CommonLayout'
import {login, getRoutesConfig} from '@/services/base/user'
import {login,getUserInfo, getRoutesConfig,getPermission,getSettings} from '@/services/base/user'
import {setAuthorization} from '@/utils/request'
import {loadRoutes} from '@/utils/routerUtil'
import {mapMutations} from 'vuex'
// import axios from 'axios'
export default {
name: 'Login',
@ -119,30 +124,10 @@ export default {
}, 1000)
}) // loadshpick
// // axios.post("http://192.168.52.166:30000/AdminUser/v1/login")
// axios.post("http://192.168.31.91:19000/AdminUser/v1/login",{
// // "mobile": "18678390480",
// // "password": "888888"
// },
// {
// // withCredentials: false
// })
// axios.post("http://192.168.31.91:19000/AdminUser/v1/routers",{
// //
// withCredentials: false,
// headers: {
// 'Content-Type': 'application/x-www-form-urlencoded',
// 'Access-Control-Allow-Origin': '*',
// 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
// }
// })
},
methods: {
...mapMutations('account', ['setUser']),
...mapMutations('account', ['setUid','setUser','setPermissions','setRoutesConfig','setSettings']),
onSubmit (e) {
e.preventDefault()
@ -160,23 +145,39 @@ export default {
this.logging = false
const loginRes = res.data
if (loginRes.code == 200) {
const user = loginRes.data.uid
console.log("user",user)
console.log("loginRes.data.access_expire",loginRes.data.access_expire)
console.log("loginRes.data.access_token",loginRes.data.access_token)
this.setUser(user)
// this.setPermissions(permissions)
setAuthorization({token: loginRes.data.access_token, expireAt: new Date(loginRes.data.access_expire*1000)})
//
getRoutesConfig().then(result => {
const uid = loginRes.data.uid
setAuthorization({token: loginRes.data.access_token, expireAt: new Date(loginRes.data.access_expire*1000)}) // token
this.setUid(uid) // id
getUserInfo().then(result =>{ //
console.log("UserInforesult:",result)
const UserInfo = result.data.data.user_info
console.log("UserInfo",UserInfo)
this.setUser(UserInfo)
})
getPermission().then(result => { //
const Permission = result.data.data.permission
console.log("Permissionresult:",result)
this.setPermissions(Permission)
})
getRoutesConfig().then(result => { //
const routesConfig = result.data.data
console.log("获取路由配置",[routesConfig])
this.setRoutesConfig(routesConfig)
loadRoutes([routesConfig])
console.log("开始跳转")
this.$router.push('/dashboard/workplace')
console.log("跳转结束")
this.$message.success(loginRes.msg, 3)
})
getSettings().then(result => { //
const settings = result.data.data
this.setSettings(settings)
})
} else {
console.log("登录失败")
this.error = loginRes.message

View File

@ -0,0 +1,23 @@
// 中台用户路由
// 视图组件
const view = {
tabs: () => import('@/layouts/tabs'),
blank: () => import('@/layouts/BlankView'),
page: () => import('@/layouts/PageView')
}
// 路由组件注册
const BaseAdminRouterMap = {
Admin:{
name: '用户管理',
icon: 'idcard',
component: view.page,
authority: {
permission:[''],
}
},
}
export default BaseAdminRouterMap

View File

@ -14,7 +14,9 @@ const BaseAdminRouterMap = {
name: '用户管理',
icon: 'idcard',
component: view.page,
authority: ['Admin-All']
authority: {
permission:[''],
}
},
}

View File

@ -14,7 +14,9 @@ const BaseCompanyRouterMap = {
name: '公司管理',
icon: 'idcard',
component: view.page,
authority: ['Service-All']
authority: {
permission:[''],
}
},
}

View File

@ -14,7 +14,9 @@ const BaseConfigRouterMap = {
name: '项目管理',
icon: 'idcard',
component: view.page,
authority: ['Config-All']
authority: {
permission:[],
}
},
}

View File

@ -14,7 +14,9 @@ const BaseServiceRouterMap = {
name: '服务管理',
icon: 'idcard',
component: view.page,
authority: ['Service-All']
authority: {
permission:[''],
}
},
}

View File

@ -169,29 +169,39 @@ const view = {
name: '报工管理',
icon: 'idcard',
component: view.page,
authority: ['WorkReport-All']
authority: {
permission:['']
}
},
WorkReporList:{
name: '报工列表',
component: () => import('@/pages/base/plan/WorkReporList'),
authority: ['WorkReport-All','WorkRepor-List']
authority: {
permission:[''],
}
},
Payroll:{
name: '工资管理',
icon: 'idcard',
component: view.page,
authority: ['Payroll-All']
authority: {
permission: ['Payroll-All'],
}
},
PayrollList:{
name: '工资列表',
component: () => import('@/pages/base/plan/PayrollList'),
authority: ['Payroll-All','Payroll-List']
authority: {
permission:['Payroll-All','Payroll-List'],
}
},
PayrollSettings:{
name: '工资设置',
component: () => import('@/pages/base/plan/PayrollSettings'),
authority: ['Payroll-All','Payroll-Settings']
authority: {
permission:['Payroll-All','Payroll-Settings'],
}
},
}

View File

@ -52,10 +52,8 @@ const loginGuard = (to, from, next, options) => {
*/
const authorityGuard = (to, from, next, options) => {
// console.log("进入authorityGuard权限守卫")
const {store, message} = options
const permissions = store.getters['account/permissions'] // 获取权限数据
console.log("store.getters['account/permissions']:", permissions)
const permissions = store.getters['account/permissions'] // 获取权限数据
if (!hasAuthority(to, permissions)) { // 判断是否有权限
// 如果没有权限跳转到403页面
message.warning(`对不起,您无权访问页面: ${to.fullPath},请联系管理员`)

View File

@ -1,6 +1,46 @@
import Vue from 'vue'
import Router from 'vue-router'
import {formatRoutes} from '@/utils/routerUtil' // 引入路由格式化工具
import { formatRoutes } from '@/utils/routerUtil' // 引入路由格式化工具
// -------------------------------- 以下为刷新页面时,重新加载路由 权限 用户信息的代码 --------------------------------
import { getUserInfo, getRoutesConfig, getPermission,getSettings } from '@/services/base/user' // 刷新用户信息
import { loadRoutes } from '@/utils/routerUtil'
import store from '@/store' // 引入vuex store 实例
import xsrfHeaderName from '@/utils/request' // 引入request
import Cookie from 'js-cookie'
// 如果cookie中存在认证信息
const Authorization = Cookie.get(xsrfHeaderName).Authorization
if (Authorization != null) {
getUserInfo().then(result => { // 获取用户信息
const UserInfo = result.data.data.user_info
console.log("UserInfo: ", UserInfo)
store.commit('account/setRoutesConfig', UserInfo) // 将用户信息存入vuex
})
getPermission().then(result => { // 获取权限
const Permission = result.data.data.permission
console.log("Permission: ", Permission)
store.commit('account/setPermissions', Permission) // 将权限信息存入vuex
})
getRoutesConfig().then(result => { // 获取路由配置
const routesConfig = result.data.data
console.log("routesConfig: ", routesConfig)
store.commit('account/setRoutesConfig', routesConfig) // 将路由配置信息存入vuex
loadRoutes([routesConfig]) // 加载路由
})
getSettings().then(result => { // 获取系统配置
const settings = result.data.data
store.commit('account/setRoutesConfig', settings) // 将系统配置信息存入vuex
})
}
// -------------------------------- 以上为刷新页面时,重新加载路由 权限 用户信息的代码 --------------------------------
Vue.use(Router)
@ -14,8 +54,6 @@ const loginIgnore = { // 登录白名单
* @returns {boolean}
*/
includes(route) { // 判断路由是否包含在该配置中
console.log("route", route)
console.log("this.names.includes(route.name) || this.paths.includes(route.path)",this.names.includes(route.name) || this.paths.includes(route.path))
return this.names.includes(route.name) || this.paths.includes(route.path) // 返回true则不需要登录拦截
}
}
@ -37,4 +75,4 @@ function initRouter(isAsync) { // 初始化路由
formatRoutes(options.routes) // 格式化路由
return new Router(options) // 返回路由实例
}
export {loginIgnore, initRouter} // 导出路由配置和初始化路由方法
export { loginIgnore, initRouter } // 导出路由配置和初始化路由方法

View File

@ -1,7 +1,4 @@
import BASE_URL from '@/services/api.js';
import BASE_URL from '@/services/base/api.js';
module.exports = {
LOGIN: `${BASE_URL}/AdminUser/v1/login`,
ROUTES: `${BASE_URL}/AdminUser/v1/routers`,
USERINFO: `${BASE_URL}/AdminUser/v1/userinfo`,
PERMISSION: `${BASE_URL}/AdminUser/v1/permission`,
}

View File

@ -4,8 +4,10 @@
const BASE_URL = process.env.VUE_APP_API_BASE_URL // 获取环境变量VUE_APP_API_BASE_URL
module.exports = {
BASE_URL,
LOGIN: `${BASE_URL}/AdminUser/v1/login`,
ROUTES: `${BASE_URL}/AdminUser/v1/routers`,
USERINFO: `${BASE_URL}/AdminUser/v1/userinfo`,
PERMISSION: `${BASE_URL}/AdminUser/v1/permission`,
SETTINGS: `${BASE_URL}/AdminUser/v1/settings`,
}

View File

@ -1,12 +0,0 @@
// import {GOODS, GOODS_COLUMNS} from './api' // 引入api.js中的常量
// import {METHOD, request} from '@/utils/request'
// export async function goodsList(params) {
// return request(GOODS, METHOD.GET, params)
// }
// export async function goodsColumns() {
// return request(GOODS_COLUMNS, METHOD.GET)
// }
// export default {goodsList, goodsColumns}

View File

@ -1,4 +1,4 @@
import {LOGIN, ROUTES, USERINFO,PERMISSION} from '@/services/base/api'
import {LOGIN, ROUTES, USERINFO,PERMISSION,SETTINGS} from '@/services/base/api'
import {request, METHOD, removeAuthorization} from '@/utils/request'
/**
* 登录服务
@ -19,7 +19,7 @@ export async function login(name, password) {
* @returns {Promise<AxiosResponse<T>>}
*/
export async function getUserInfo() { // 获取用户信息
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_USER_KEY)) // 获取用户id并转换为整数
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_UID_KEY)) // 获取用户id并转换为整数
return request(USERINFO, METHOD.POST, {
uid: userId
})
@ -30,7 +30,7 @@ export async function getUserInfo() { // 获取用户信息
* @returns {Promise<AxiosResponse<T>>}
*/
export async function getRoutesConfig() { // 获取路由配置
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_USER_KEY)) // 获取用户id并转换为整数
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_UID_KEY)) // 获取用户id并转换为整数
return request(ROUTES, METHOD.POST, {
uid:userId
})
@ -42,23 +42,39 @@ export async function getRoutesConfig() { // 获取路由配置
* @returns {Promise<AxiosResponse<T>>}
*/
export async function getPermission() { // 获取权限配置
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_USER_KEY)) // 获取用户id并转换为整数
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_UID_KEY)) // 获取用户id并转换为整数
return request(PERMISSION, METHOD.POST, {
uid:userId
})
}
/**
* 获取用户设置
* @param uid
* @returns {Promise<AxiosResponse<Tuple>>}
*/
export async function getSettings() { // 获取用户设置
const userId = parseInt(localStorage.getItem(process.env.VUE_APP_UID_KEY)) // 获取用户id并转换为整数
return request(SETTINGS, METHOD.POST, {
uid:userId
})
}
/**
* 退出登录
*/
export function logout() {
localStorage.removeItem(process.env.VUE_APP_ROUTES_KEY) // 删除路由配置
localStorage.removeItem(process.env.VUE_APP_PERMISSIONS_KEY) // 删除权限配置
localStorage.removeItem(process.env.VUE_APP_USER_KEY) // 删除用户id
localStorage.removeItem(process.env.VUE_APP_USER_KEY) // 删除用户信息
localStorage.removeItem(process.env.VUE_APP_UID_KEY) // 删除用户id
removeAuthorization()
}
export default {
login,
logout,
getRoutesConfig
getRoutesConfig,
getPermission,
getUserInfo,
getSettings
}

View File

@ -1,7 +1,7 @@
import userService from './base/user'
import dataSource from './base/dataSource'
export {
userService,
dataSource
}

View File

@ -1,16 +1,30 @@
export default {
namespaced: true,
state: {
uid: 0,
user: undefined, // 用户信息
permissions: null, // 权限
routesConfig: null // 路由配置
permissions: undefined, // 权限
routesConfig: undefined, // 路由配置
settings: undefined // 用户配置
},
getters: {
uid: state => { // 用户id
if (!state.uid) { // 如果没有用户uid
try {
const uid = localStorage.getItem(process.env.VUE_APP_UID_KEY) // 获取用户id
state.uid = uid // 将用户信息赋值给state.user
} catch (e) { // 捕获异常
console.error(e)
}
}
return state.uid // 如果有用户信息,直接返回
},
user: state => { // 用户信息
if (!state.user) { // 如果没有用户信息
try {
const user = localStorage.getItem(process.env.VUE_APP_USER_KEY) // 获取用户信息
state.user = user // 将用户信息赋值给state.user
state.user = JSON.parse(user) // 将用户信息赋值给state.user
state.user = state.user ? state.user : [] // 如果用户信息为空,赋值为空对象
} catch (e) { // 捕获异常
console.error(e)
}
@ -24,7 +38,7 @@ export default {
state.permissions = JSON.parse(permissions) // 将权限赋值给state.permissions
state.permissions = state.permissions ? state.permissions : [] // 如果state.permissions为空则赋值为空数组
} catch (e) { // 捕获异常
console.error(e.message)
// console.error(e.message)
}
}
return state.permissions // 如果有权限,则返回权限
@ -41,12 +55,29 @@ export default {
}
}
return state.routesConfig // 如果有路由配置,则返回路由配置
},
settings: state => { // 用户配置
if (!state.settings) { // 如果没有用户配置
try {
const settings = localStorage.getItem(process.env.VUE_APP_USER_SETTINGS_KEY) // 获取用户配置
state.settings = JSON.parse(settings) // 将字符串转换为json对象
state.settings = state.settings ? state.settings : {} // 如果state.settings为null则赋值为空对象
} catch (e) { // 捕获异常
console.error(e.message)
}
}
return state.settings // 如果有用户配置,则返回用户配置
}
},
mutations: {
setUid (state, uid) { // 设置用户uid
state.uid = uid
localStorage.setItem(process.env.VUE_APP_UID_KEY, JSON.stringify(uid))// 将所有用户信息存储到process.env.VUE_APP_UID_KEY key中
},
setUser (state, user) { // 设置用户信息
state.user = user
localStorage.setItem(process.env.VUE_APP_USER_KEY, user)// 将所有用户信息存储到process.env.VUE_APP_USER_KEY中
localStorage.setItem(process.env.VUE_APP_USER_KEY, JSON.stringify(user))// 将所有用户信息存储到process.env.VUE_APP_USER_KEY中
},
setPermissions(state, permissions) { // 设置权限
state.permissions = permissions
@ -54,8 +85,11 @@ export default {
},
setRoutesConfig(state, routesConfig) { // 设置路由配置
state.routesConfig = routesConfig
console.log("存入路由配置:", routesConfig)
localStorage.setItem(process.env.VUE_APP_ROUTES_KEY, JSON.stringify(routesConfig)) // 将所有路由信息存储到process.env.VUE_APP_ROUTES_KEY中
},
setSettings(state, settings) { // 设置用户配置
state.settings = settings
localStorage.setItem(process.env.VUE_APP_USER_SETTINGS_KEY, JSON.stringify(settings)) // 将所有用户配置信息存储到process.env.VUE_APP_USER_SETTINGS_KEY中
}
}
}

View File

@ -11,8 +11,17 @@
* @param roles 用户角色集合
* @returns {boolean}
*/
function hasAuthority() { // 权限校验
function hasAuthority(to, permissions) { // 权限校验
// 循环 to.meta.authority.permission 集合
if (to.meta && to.meta.authority.permission.length > 0) {
for (let i = 0; i < to.meta.authority.permission.length; i++) {
// 判断用户权限集合中是否包含 to.meta.authority.permission 中的权限
if (permissions.includes(to.meta.authority.permission[i])) {
return false
}
}
}
// 如果 to.meta.authority.permission 匹配到了 permissions 中的某个权限就返回false
return true // 如果都满足返回true
}

View File

@ -33,6 +33,7 @@ const METHOD = {
* @returns {Promise<AxiosResponse<T>>}
*/
async function request(url, method, params, config) { // 请求方法
axios.defaults.headers.common[xsrfHeaderName] = Cookie.get(xsrfHeaderName)
switch (method) {
case METHOD.GET:
return axios.get(url, {params, ...config})

View File

@ -1,5 +1,5 @@
import routerMap from '@/router/async/router.map'
import {mergeI18nFromRoutes} from '@/utils/i18n'
import { mergeI18nFromRoutes } from '@/utils/i18n'
import Router from 'vue-router'
import deepMerge from 'deepmerge'
import basicOptions from '@/router/async/config.async'
@ -16,7 +16,7 @@ let appOptions = {
* @param options
*/
function setAppOptions(options) { // 设置应用配置
const {router, store, i18n} = options // 获取路由、状态管理、国际化
const { router, store, i18n } = options // 获取路由、状态管理、国际化
appOptions.router = router // 路由
appOptions.store = store // 状态管理
appOptions.i18n = i18n // 国际化
@ -34,14 +34,14 @@ function parseRoutes(routesConfig, routerMap) { // 解析路由
let router = undefined, routeCfg = {} // 初始化路由和路由配置
if (typeof item === 'string') { // 如果路由配置是字符串
router = routerMap[item] // 从 routerMap 中获取路由
routeCfg = {path: (router && router.path) || item, router: item} // 路由配置获取路由的 path 和 router
routeCfg = { path: (router && router.path) || item, router: item } // 路由配置获取路由的 path 和 router
} else if (typeof item === 'object') { // 如果路由配置是对象
router = routerMap[item.router] // 从 routerMap 中获取路由
routeCfg = item // 路由配置为 item
}
if (!router) { // 如果没有获取到路由 或者是路由不为数组及对象
console.warn(`can't find register for router ${routeCfg.router}, please register it in advance.`) // 打印警告
router = typeof item === 'string' ? {path: item, name: item} : item // 如果路由配置是字符串,路由为 {path: item, name: item},否则为 item
router = typeof item === 'string' ? { path: item, name: item } : item // 如果路由配置是字符串,路由为 {path: item, name: item},否则为 item
}
// 从 router 和 routeCfg 解析路由
const meta = { // 路由元信息
@ -68,12 +68,12 @@ function parseRoutes(routesConfig, routerMap) { // 解析路由
}
})
Object.assign(meta, cfgMeta) // 合并路由元信息和路由配置元信息
const route = {
const route = {
path: routeCfg.path || router.path || routeCfg.router, // 路由路径
name: routeCfg.name || router.name, // 路由名称
component: router.component, // 路由组件
redirect: routeCfg.redirect || router.redirect, // 重定向
meta: {...meta, authority: meta.authority || '*'} // 路由元信息
meta: { ...meta, authority: meta.authority || '*' } // 路由元信息
}
if (routeCfg.invisible || router.invisible) { // 如果路由配置或者路由不可见
route.meta.invisible = true
@ -86,14 +86,39 @@ function parseRoutes(routesConfig, routerMap) { // 解析路由
return routes
}
// 根据权限过滤路由
function filterRoutesConfig(routes, permissions) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (hasPermission(permissions, tmp)) {
if (tmp.children) {
tmp.children = filterRoutesConfig(tmp.children, permissions)
}
res.push(tmp)
}
})
return res
}
// 判断是否有权限
function hasPermission(permissions, route) {
if (route.meta && route.meta.authority.permission) {
return permissions.some(permission => {
return route.meta.authority.permission === '' || route.meta.authority.permission === permission
})
} else {
return true
}
}
/**
* 加载路由
* @param routesConfig {RouteConfig[]} 路由配置
*/
function loadRoutes(routesConfig) { // 加载路由
console.log("加载路由")
console.log("+++++routesConfig:",routesConfig)
console.log("+++++arguments:",arguments)
//兼容 0.6.1 以下版本
/*************** 兼容 version < v0.6.1 *****************/
@ -110,24 +135,28 @@ function loadRoutes(routesConfig) { // 加载路由
/*************** 兼容 version < v0.6.1 *****************/
// 应用配置
const {router, store, i18n} = appOptions
const { router, store, i18n } = appOptions
const Permission = store.getters['account/permissions'] // 获取权限
console.log("======Permission:",Permission)
if (routesConfig) { // 如果routesConfig已经存在
store.commit('account/setRoutesConfig', routesConfig) // 通过store的account模块的setRoutesConfig方法更新路由配置
} else {
routesConfig = store.getters['account/routesConfig'] // 通过store的account模块的routesConfig方法获取路由配置
}
// 如果 routesConfig 有值,则更新到本地,否则从本地获取
console.log("=====setRoutesConfig:", routesConfig)
if (routesConfig) { // 如果routesConfig已经存在
console.log("routesConfig存在store.commit('account/setRoutesConfig', routesConfig)")
store.commit('account/setRoutesConfig', routesConfig) // 通过store的account模块的setRoutesConfig方法更新路由配置
} else {
console.log("routesConfig不存在routesConfig = store.state.account.routesConfig")
routesConfig = store.getters['account/routesConfig'] // 通过store的account模块的routesConfig方法获取路由配置
console.log("=====getRoutesConfig:", routesConfig)
}
// 根据权限过滤路由配置
const filteredRoutesConfig = filterRoutesConfig(routesConfig, Permission) // 根据权限过滤路由配置
console.log("=====filteredRoutesConfig:", filteredRoutesConfig)
// routesConfig = filteredRoutesConfig // 路由配置等于过滤后的路由配置
// 如果开启了异步路由,则加载异步路由配置
const asyncRoutes = store.state.setting.asyncRoutes // 获取store的setting模块的asyncRoutes
console.log("asyncRoutes",asyncRoutes)
if (asyncRoutes) { // 如果动态路由存在
console.log("routesConfig && routesConfig.length > 0",routesConfig.length > 0)
console.log("routesConfig && routesConfig.length > 0", routesConfig.length > 0)
if (routesConfig && routesConfig.length > 0) { // 如果本地路由配置存在 并且 数量大于0
const routes = parseRoutes(routesConfig, routerMap) // 解析路由
// 合并路由 生成路由表
@ -135,9 +164,12 @@ function loadRoutes(routesConfig) { // 加载路由
// 格式化路由
formatRoutes(finalRoutes)
console.log('最终路由表finalRoutes:', finalRoutes) // 最终路由表
router.options = {...router.options, routes: finalRoutes} // 路由配置
router.matcher = new Router({...router.options, routes:[]}).matcher // 重置路由
router.addRoutes(finalRoutes) // 添加路由
router.options = { ...router.options, routes: finalRoutes } // 路由配置
router.matcher = new Router({ ...router.options, routes: [] }).matcher // 重置路由
// router.addRoutes(finalRoutes) // 添加路由
for (let x of finalRoutes) {
router.addRoute(x)
}
}
}
// 提取路由国际化数据
@ -150,6 +182,8 @@ function loadRoutes(routesConfig) { // 加载路由
}
}
/**
* 合并路由
* @param target {Route[]}
@ -175,7 +209,7 @@ function deepMergeRoutes(target, source) {
const routesMap = {} // 路由映射表
routes.forEach(item => { // 遍历路由
routesMap[item.path] = { // 将路由添加到路由映射表中
...item,
...item,
children: item.children ? mapRoutes(item.children) : undefined // 如果路由有子路由则递归调用mapRoutes方法
}
})
@ -207,7 +241,7 @@ function deepMergeRoutes(target, source) {
*/
function formatRoutes(routes) { // 格式化路由
routes.forEach(route => { // 遍历路由
const {path} = route // 获取路由的path
const { path } = route // 获取路由的path
if (!path.startsWith('/') && path !== '*') { // 如果路由的path不是以/开头 并且 不是*
route.path = '/' + path // 将路由的path添加/
}
@ -223,16 +257,16 @@ function formatRoutes(routes) { // 格式化路由
function formatAuthority(routes, pAuthorities = []) { // 格式化路由的权限配置
routes.forEach(route => { // 遍历路由
const meta = route.meta // 获取路由的meta
const defaultAuthority = pAuthorities[pAuthorities.length - 1] || {permission: '*'} // 获取默认权限 首先获取父级路由权限配置集合的最后一个元素,如果没有则获取{permission: '*'}
const defaultAuthority = pAuthorities[pAuthorities.length - 1] || { permission: '*' } // 获取默认权限 首先获取父级路由权限配置集合的最后一个元素,如果没有则获取{permission: '*'}
if (meta) { // 如果meta存在
let authority = {} // 权限
if (!meta.authority) { // 如果meta.authority不存在
authority = defaultAuthority // 权限为默认权限
}else if (typeof meta.authority === 'string') { // 如果meta.authority是字符串
} else if (typeof meta.authority === 'string') { // 如果meta.authority是字符串
authority.permission = meta.authority // 权限的permission为meta.authority
} else if (typeof meta.authority === 'object') { // 如果meta.authority是对象
authority = meta.authority // 权限为meta.authority
const {role} = authority // 获取权限的role
const { role } = authority // 获取权限的role
if (typeof role === 'string') { // 如果权限的role是字符串
authority.role = [role] // 权限的role为数组
}
@ -243,7 +277,7 @@ function formatAuthority(routes, pAuthorities = []) { // 格式化路由的权
meta.authority = authority // 将权限赋值给meta.authority
} else { // 如果meta不存在
const authority = defaultAuthority // 权限为默认权限
route.meta = {authority} // 将权限赋值给meta
route.meta = { authority } // 将权限赋值给meta
}
route.meta.pAuthorities = pAuthorities // 将父级路由权限配置集合赋值给meta.pAuthorities
if (route.children) { // 如果路由有子路由 递归调用formatAuthority方法
@ -269,8 +303,8 @@ function getI18nKey(path) { // 从路由 path 解析 i18n key
* @param options
*/
function loadGuards(guards, options) { // 加载导航守卫 guards
const {beforeEach, afterEach} = guards // 解构出 beforeEach 和 afterEach
const {router} = options // 解构出 router
const { beforeEach, afterEach } = guards // 解构出 beforeEach 和 afterEach
const { router } = options // 解构出 router
beforeEach.forEach(guard => { // 遍历 beforeEach
if (guard && typeof guard === 'function') { // 如果guard存在 并且 guard是函数
router.beforeEach((to, from, next) => guard(to, from, next, options)) // 调用router.beforeEach方法
@ -283,4 +317,4 @@ function loadGuards(guards, options) { // 加载导航守卫 guards
})
}
export {parseRoutes, loadRoutes, formatAuthority, getI18nKey, loadGuards, deepMergeRoutes, formatRoutes, setAppOptions}
export { parseRoutes, loadRoutes, formatAuthority, getI18nKey, loadGuards, deepMergeRoutes, formatRoutes, setAppOptions }