[release] 4.0.0 (#1291)

* fix[ExternalLink]: fixed bug when url include chinese #1182

* feature: support  Spanish(#1196)

* fix[MockJS]: fix bug with withCredentials after using mockjs  (#1194)

* 修复 Mock 导致请求丢失 Cookie 的问题

修复 Mock 导致 Cookie 丢失的问题,只有在 XHR.open() 周期时,自定义的 withCredentials 会被挂载,此时检查是否是未被拦截的 xhr,并挂载自定义的 withCredentials ,无则默认为 false

* update readme

* perf[tagsView]: refactor the moveToTarget function (#1195)

* fix[tagsView]:fixed visited view move to currentTag

* edit the scroll regular friendly

* tweak

* fix[tagsView]: fixed moveToCurrentTag bug

* feature: add pagination component (#1213)

* fix[TagsView]: fixed update tags title demo bug (#1223)

* chore: temporary hack cssnano bug #1222

* [release] 3.9.2

* chore: restore the hack of cssnano bug

https://github.com/cssnano/cssnano/issues/643

* add an example of sort data by table  (#1236)

* feature: add drag select component (#1249)

* feat: perfect migrate to @vue/cli-service, upgrade vue babel version (#1267)

* feat: perfect migrate to @vue/cli-service, upgrade vue babel version

1. update to @vue/cli-service@3.0.5, @babel/core@7.0.0
2. use vue-cli service replace config file in build/ and config/
3. upgrade vue and babel configuration
4. solve the svg-sprite config problem #980

refs: #932 #1087  #980 #1056

* fix: fix breadcrumb dependency

* fix: fix index template and static assets load with vue-cli 3

* fix: fix import driver.js in guide page

* refactor(mock): mak mock api compatible with both web-view and webpack server

1. 把 Mockjs 功能移到 server 端中间件,同时也兼容前端直接劫持 XHR
2. dev 环境下默认作为 express 中间件通过 webpack server 提供 mock api
3. prod 构建时,默认在前端用 Mockjs 劫持 XHR

benefits:
  - dev 开发调试时能直接看到 XHR 请求,方便调试网络,能和后端对接联调
  - 避开在开发时因为 Mockjs 引起的网络 bug
  - prod 构建时劫持 XHR,保证本项目的 Github Pages preview 能正常显示 (逻辑和 error-log 一样)
  - 前后台使用的 mock 是同一份代码,不会增加维护负担

ref: [#562](https://github.com/PanJiaChen/vue-element-admin/issues/562#issuecomment-378116233)

* update requires the lowest version of node

* add favicon

* fix(TreeTable): fix `Array.prototype.concat` on custom-tree-table page

* update

* add test

* fix bug

* fix[Charts]: fixed charts resize mixins bug  #1285 (#1290)

* perf[Tinymce]: add searchreplace plugin

* perf[avatar]:minimize the selected area of avatar on the mobile phone when user clicked avatar (#1304)

* refine css

* fix[DragSelect]: fixed querySelectorAll bug

* perf[DragSelect]: add $listeners

* fix link

* fix[Breadcurmb]: fixed pathCompile bug

* fix[Breadcurmb]: fixed router-link bug

* perf[style]: use webpack alias instead of hard code src path (#1338)

* perf[style]: use webpack alias instead of hard code src path

* add sponsors

* fix import path bug

* update vue-router to fixed url path for non ascii urls #1362

* fix[Pagination]: apply PageSizes property to el-pagination  (#1355)

Apply PageSizes property to el-pagination

* update dependence

* add tui.editor (#1374)

* tweak

* add preview

* fix return back bug

* update guide page

* fix[Tinymce]: fixed fullScreen bug #1400

* feat[Breadcrumb]: add hide Breadcrumb option #1442

* perf: use WeChat 7.0 new version icon color

* refactor[login]: refactor login page style

* perf[ScrollPane]: refine moveToTarget code (#1460)

* feature[PDF]: add PDF demo (#1469)

* perf[v-permission]: refine v-permission demo

* perf[Sidebar]: refine sidebar store #1473 (#1474)

* refine: GetUserInfo error message

* fix typo (#1505)

* perf: add sidebar width to variables.scss (#1494)

* tweak

* fix[ThemePicker]: fixed bug when oldVal is null (#1517)

* update README.md

* fix[Breadcrumb]: fixed eslint error (#1521)

* fix[DndList]: fixed drag bug (#1527)

https://github.com/PanJiaChen/vue-element-admin/issues/1524

* pref[Hamburger]: refactor Hamburger component (#1528)

* 美化侧栏菜单切换按钮

* tweak

* perf[Login Form]: optimize eye icon style (#1545)

* optimiz: eye icon style for login form

* change eye-open svg

* perf[Sticky]: export reset method (#1550)

* perf[Sticky]: refine width default value

* perf[utils]: refine parseTime function (#1546)

* 优化 parseTime

修复传入的时间戳是字符串类型,不能转换时间的问题
例:parseTime("1548221490638")

* Update index.js

* perf[UploadExcel]: optimized code (#1552)

* perf: adjust the import order to make it more elegant #1537

* perf[Sidebar]: use sass variables in vue template

* perf[Style]: optimize the sidebar style to make it better to set (#1568)

* perf[SizeSelect]: add default size option (#1566)

* fix[SIdebar]: fixed bug in mobile #1567 (#1569)

* perf: fixed eslint errors

* perf[Lang]: make up for miss keywords

* perf: optimize some code

* perf[Navbar]: refactor navbar style

* perf[Login]: refine css

* feature[Navbar]: add header-search component(#1591)

* fix[Screenfull]: fix screenfull click bug

* perf[Screenfull]: refactor screenfull component

* fix[Screenfull]: fix screenfull bug (#1603)

* fix typo

* fearure[TagsView]: add affix option (#1577)

* perf[utils]: optimize code

* perf[utils]: optimizate variable name

* perf[Navbar]: add scroll bar when the subMenu is too long (#1619)

* perf[ThemePicker]: refine updateStyle function (#554)

* theme replacing should cut tons of irrelevant css

* perf[ResizeHandler]: optimized the judgment of isMobile (#1633)

perf[ResizeHandler]: optimized the judgment of isMobile

*  fix[Sidebar]: fixed infinite loop bug(#1333)

* fixed infinite loop Bug when in hasOneShowingChild Edit the onlyOneChild

* tweak

* fix[Sidebar]: data should return a object

* perf[Sidebar]: optimize code logic (#1349)

* fix[TagsView]: fixed refresh affixed-tag bug (#1653)

* perf[utils.js]: refactor byteLength function (#1650)

* perf[TagsView]: refine code

* perf[TagsView]: set the scrollPane as a business component (#1660)

* fix[DragTable]: support multiple drag-table (#1666)

* perf[Tree-Table]: refactor tree-table

* perf[Tree-Table]: organize the structure and add documentation (#1673)

* fix[Sidebar]: fixed nested router hover bug

* update version

* set preserveWhitespace

* lint code

* fix jest test case

* update config

* bump

* remove empty file

* docs: add link

* fix[Sidebar]: fixed collapse animation problem (#1690)

* fix[Tree-Table]: fixed update item data bug (#1692)

* fix[Waves-Directive]: fixed v-waves does not support update (#1705)

* update husky

* rm cli-plugin-eslint

* add settings (#1707)

* refine settings

* fix[utils]: fixed param2Obj not decoding plus sign (#1712)

* feature[Directive]: add auto-height table directive (#1702)

* fix bug

* feature[Permission]: add role permission management page (#1605)

* feature[Excel]: support export merged header export (#1718)

* feature[Excel]: add export merge header excel demo

* lint

* refine theme color

* add role mock

* tweak mock

* fix[Excel]: fixed export merge-header excel bug

* refine code

* add ThemePicker to setting

* fix[HeaderSearch]: fixed bug in vue2.6+ (#1733)

* fix[Sticky]: fixed bug when set stickyTop

* perf[Sticky]: refine demo

* refine code

* tweak mock

* vuex add namespaced

* fix[Excel]: fixed export bug (#1736)

* rm

* refactor permission

* perf[ThemePicker]: add predefine (#1743)

* fix[Utils]: fixed deepClone error msg (#1748)

* feature: add fixedHeader settings

* fix style in mobile

* fix chore

* perf[Eslint]: update eslint rules

* feature: add create template (#1762)

* add comment

* update vue.config.js

* feature: add sidebar logo (#1767)

* rm

* perf settings

* bump

* refine script and css

* update

* refine settings

* refine config

* update docs

* refine

* rm

* fix jest

* add theme setting

* dump vue-cli

* perf: remove redundant code

* update element-ui

* fix sticky demo bug

* docs

* fixed password input  bug

* refine login form css

* remove tree-table

* update version

* mock error

* refine layout name

* refine
This commit is contained in:
花裤衩
2019-04-01 17:07:16 +08:00
committed by GitHub
parent 96d3cfa215
commit b94e69be6f
212 changed files with 3517 additions and 3366 deletions

View File

@@ -9,9 +9,7 @@ const getters = {
avatar: state => state.user.avatar,
name: state => state.user.name,
introduction: state => state.user.introduction,
status: state => state.user.status,
roles: state => state.user.roles,
setting: state => state.user.setting,
permission_routes: state => state.permission.routes,
addRoutes: state => state.permission.addRoutes,
errorLogs: state => state.errorLog.logs

View File

@@ -4,6 +4,7 @@ import app from './modules/app'
import errorLog from './modules/errorLog'
import permission from './modules/permission'
import tagsView from './modules/tagsView'
import settings from './modules/settings'
import user from './modules/user'
import getters from './getters'
@@ -15,6 +16,7 @@ const store = new Vuex.Store({
errorLog,
permission,
tagsView,
settings,
user
},
getters

View File

@@ -1,59 +1,64 @@
import Cookies from 'js-cookie'
const app = {
state: {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
device: 'desktop',
language: Cookies.get('language') || 'en',
size: Cookies.get('size') || 'medium'
const state = {
sidebar: {
opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
withoutAnimation: false
},
mutations: {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
device: 'desktop',
language: Cookies.get('language') || 'en',
size: Cookies.get('size') || 'medium'
}
const mutations = {
TOGGLE_SIDEBAR: state => {
state.sidebar.opened = !state.sidebar.opened
state.sidebar.withoutAnimation = false
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
SET_LANGUAGE: (state, language) => {
state.language = language
Cookies.set('language', language)
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
}
},
actions: {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setLanguage({ commit }, language) {
commit('SET_LANGUAGE', language)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},
TOGGLE_DEVICE: (state, device) => {
state.device = device
},
SET_LANGUAGE: (state, language) => {
state.language = language
Cookies.set('language', language)
},
SET_SIZE: (state, size) => {
state.size = size
Cookies.set('size', size)
}
}
export default app
const actions = {
toggleSideBar({ commit }) {
commit('TOGGLE_SIDEBAR')
},
closeSideBar({ commit }, { withoutAnimation }) {
commit('CLOSE_SIDEBAR', withoutAnimation)
},
toggleDevice({ commit }, device) {
commit('TOGGLE_DEVICE', device)
},
setLanguage({ commit }, language) {
commit('SET_LANGUAGE', language)
},
setSize({ commit }, size) {
commit('SET_SIZE', size)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -1,17 +1,23 @@
const errorLog = {
state: {
logs: []
},
mutations: {
ADD_ERROR_LOG: (state, log) => {
state.logs.push(log)
}
},
actions: {
addErrorLog({ commit }, log) {
commit('ADD_ERROR_LOG', log)
}
const state = {
logs: []
}
const mutations = {
ADD_ERROR_LOG: (state, log) => {
state.logs.push(log)
}
}
export default errorLog
const actions = {
addErrorLog({ commit }, log) {
commit('ADD_ERROR_LOG', log)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -34,32 +34,36 @@ export function filterAsyncRoutes(routes, roles) {
return res
}
const permission = {
state: {
routes: [],
addRoutes: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
},
actions: {
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
const state = {
routes: [],
addRoutes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
export default permission
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
}

View File

@@ -0,0 +1,32 @@
import defaultSettings from '@/settings'
const { showSettings, tagsView, fixedHeader, sidebarLogo, theme } = defaultSettings
const state = {
theme: theme,
showSettings: showSettings,
tagsView: tagsView,
fixedHeader: fixedHeader,
sidebarLogo: sidebarLogo
}
const mutations = {
CHANGE_SETTING: (state, { key, value }) => {
if (state.hasOwnProperty(key)) {
state[key] = value
}
}
}
const actions = {
changeSetting({ commit }, data) {
commit('CHANGE_SETTING', data)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -1,161 +1,166 @@
const tagsView = {
state: {
visitedViews: [],
cachedViews: []
},
mutations: {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
},
DEL_CACHED_VIEW: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews.splice(index, 1)
break
}
}
},
const state = {
visitedViews: [],
cachedViews: []
}
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path
const mutations = {
ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews = state.cachedViews.slice(index, index + 1)
break
}
}
},
)
},
ADD_CACHED_VIEW: (state, view) => {
if (state.cachedViews.includes(view.name)) return
if (!view.meta.noCache) {
state.cachedViews.push(view.name)
}
},
DEL_ALL_VISITED_VIEWS: state => {
// keep affix tags
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags
},
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
},
UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) {
state.visitedViews.splice(i, 1)
break
}
}
},
DEL_CACHED_VIEW: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews.splice(index, 1)
break
}
}
},
actions: {
addView({ dispatch }, view) {
dispatch('addVisitedView', view)
dispatch('addCachedView', view)
},
addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view)
},
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},
delView({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delVisitedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},
DEL_OTHERS_VISITED_VIEWS: (state, view) => {
state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path
})
},
DEL_OTHERS_CACHED_VIEWS: (state, view) => {
for (const i of state.cachedViews) {
if (i === view.name) {
const index = state.cachedViews.indexOf(i)
state.cachedViews = state.cachedViews.slice(index, index + 1)
break
}
}
},
delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delOthersVisitedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersCachedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_CACHED_VIEWS', view)
resolve([...state.cachedViews])
})
},
DEL_ALL_VISITED_VIEWS: state => {
// keep affix tags
const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags
},
DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = []
},
delAllViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delAllVisitedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
},
updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view)
UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) {
if (v.path === view.path) {
v = Object.assign(v, view)
break
}
}
}
}
export default tagsView
const actions = {
addView({ dispatch }, view) {
dispatch('addVisitedView', view)
dispatch('addCachedView', view)
},
addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view)
},
addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view)
},
delView({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delVisitedView', view)
dispatch('delCachedView', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delVisitedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_VISITED_VIEW', view)
resolve([...state.visitedViews])
})
},
delCachedView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews])
})
},
delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delOthersVisitedViews', view)
dispatch('delOthersCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delOthersVisitedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_VISITED_VIEWS', view)
resolve([...state.visitedViews])
})
},
delOthersCachedViews({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_OTHERS_CACHED_VIEWS', view)
resolve([...state.cachedViews])
})
},
delAllViews({ dispatch, state }, view) {
return new Promise(resolve => {
dispatch('delAllVisitedViews', view)
dispatch('delAllCachedViews', view)
resolve({
visitedViews: [...state.visitedViews],
cachedViews: [...state.cachedViews]
})
})
},
delAllVisitedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_VISITED_VIEWS')
resolve([...state.visitedViews])
})
},
delAllCachedViews({ commit, state }) {
return new Promise(resolve => {
commit('DEL_ALL_CACHED_VIEWS')
resolve([...state.cachedViews])
})
},
updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view)
}
}
export default {
namespaced: true,
state,
mutations,
actions
}

View File

@@ -1,144 +1,128 @@
import { loginByUsername, logout, getUserInfo } from '@/api/login'
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
const user = {
state: {
user: '',
status: '',
code: '',
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: [],
setting: {
articlePlatform: []
}
const state = {
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: []
}
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
},
mutations: {
SET_CODE: (state, code) => {
state.code = code
},
SET_TOKEN: (state, token) => {
state.token = token
},
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction
},
SET_SETTING: (state, setting) => {
state.setting = setting
},
SET_STATUS: (state, status) => {
state.status = status
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
}
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction
},
actions: {
// 用户名登录
LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim()
return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(response => {
const data = response.data
commit('SET_TOKEN', data.token)
setToken(response.data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// 获取用户信息
GetUserInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getUserInfo(state.token).then(response => {
// 由于mockjs 不支持自定义状态码只能这样hack
if (!response.data) {
reject('Verification failed, please login again.')
}
const data = response.data
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', data.roles)
} else {
reject('getInfo: roles must be a non-null array!')
}
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
resolve(response)
}).catch(error => {
reject(error)
})
})
},
// 第三方验证登录
// LoginByThirdparty({ commit, state }, code) {
// return new Promise((resolve, reject) => {
// commit('SET_CODE', code)
// loginByThirdparty(state.status, state.email, state.code).then(response => {
// commit('SET_TOKEN', response.data.token)
// setToken(response.data.token)
// resolve()
// }).catch(error => {
// reject(error)
// })
// })
// },
// 登出
LogOut({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resolve()
}).catch(error => {
reject(error)
})
})
},
// 前端 登出
FedLogOut({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
removeToken()
resolve()
})
},
// 动态修改权限
ChangeRoles({ commit, dispatch }, role) {
return new Promise(resolve => {
commit('SET_TOKEN', role)
setToken(role)
getUserInfo(role).then(response => {
const data = response.data
commit('SET_ROLES', data.roles)
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单
resolve()
})
})
}
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
}
}
export default user
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)
})
})
},
// get user info
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const { data } = response
if (!data) {
reject('Verification failed, please Login again.')
}
const { roles, name, avatar, introduction } = data
// roles must be a non-empty array
if (!roles || roles.length <= 0) {
reject('getInfo: roles must be a non-null array!')
}
commit('SET_ROLES', roles)
commit('SET_NAME', name)
commit('SET_AVATAR', avatar)
commit('SET_INTRODUCTION', introduction)
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resetRouter()
resolve()
}).catch(error => {
reject(error)
})
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resolve()
})
},
// Dynamically modify permissions
changeRoles({ commit, dispatch }, role) {
return new Promise(async resolve => {
const token = role + '-token'
commit('SET_TOKEN', token)
setToken(token)
const { roles } = await dispatch('getInfo')
resetRouter()
// generate accessible routes map based on roles
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
// dynamically add accessible routes
router.addRoutes(accessRoutes)
resolve()
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}