refine code

This commit is contained in:
Pan 2019-03-18 18:07:55 +08:00
parent c93d88a348
commit 8b382e1e15
13 changed files with 167 additions and 165 deletions

View File

@ -13,7 +13,7 @@ for (let i = 0; i < count; i++) {
author: '@first', author: '@first',
reviewer: '@first', reviewer: '@first',
title: '@title(5, 10)', title: '@title(5, 10)',
content_short: '我是测试数据', content_short: 'mock data',
content: baseContent, content: baseContent,
forecast: '@float(0, 100, 2, 2)', forecast: '@float(0, 100, 2, 2)',
importance: '@integer(1, 3)', importance: '@integer(1, 3)',

View File

@ -1,10 +1,10 @@
import login from './login' import user from './user'
import role from './role' import role from './role'
import article from './article' import article from './article'
import search from './remoteSearch' import search from './remoteSearch'
export default [ export default [
...login, ...user,
...role, ...role,
...article, ...article,
...search ...search

View File

@ -8,9 +8,10 @@ for (let i = 0; i < count; i++) {
name: '@first' name: '@first'
})) }))
} }
NameList.push({ name: 'mockPan' }) NameList.push({ name: 'mock-Pan' })
export default [ export default [
// username search
{ {
url: '/search/user', url: '/search/user',
type: 'get', type: 'get',
@ -23,14 +24,15 @@ export default [
return { items: mockNameList } return { items: mockNameList }
} }
}, },
// transaction list
{ {
url: '/transaction/list', url: '/transaction/list',
type: 'get', type: 'get',
response: _ => { response: _ => {
const count = 20
return { return {
total: count, total: 20,
[`items|${count}`]: [{ 'items|20': [{
order_no: '@guid()', order_no: '@guid()',
timestamp: +Mock.Random.date('T'), timestamp: +Mock.Random.date('T'),
username: '@name()', username: '@name()',

View File

@ -1,48 +1,57 @@
const userMap = {
const tokens = {
admin: { admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
const users = {
'admin-token': {
roles: ['admin'], roles: ['admin'],
token: 'admin', introduction: 'I am a super administrator',
introduction: '我是超级管理员',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin' name: 'Super Admin'
}, },
editor: { 'editor-token': {
roles: ['editor'], roles: ['editor'],
token: 'editor', introduction: 'I am an editor',
introduction: '我是编辑',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif', avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor' name: 'Normal Editor'
} }
} }
export default [ export default [
// user login
{ {
url: '/login/login', url: '/user/login',
type: 'post', type: 'post',
response: config => { response: config => {
const { username } = config.body const { username } = config.body
return userMap[username] return tokens[username]
} }
}, },
// get user info
{ {
url: '/login/logout', url: '/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
return users[token]
}
},
// user logout
{
url: '/user/logout',
type: 'post', type: 'post',
response: _ => { response: _ => {
return { return {
data: 'success' data: 'success'
} }
} }
},
{
url: '/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
if (userMap[token]) {
return userMap[token]
} else {
return false
}
}
} }
] ]

View File

@ -1,25 +1,14 @@
import request from '@/utils/request' import request from '@/utils/request'
export function loginByUsername(username, password) { export function login(data) {
const data = {
username,
password
}
return request({ return request({
url: '/login/login', url: '/user/login',
method: 'post', method: 'post',
data data
}) })
} }
export function logout() { export function getInfo(token) {
return request({
url: '/login/logout',
method: 'post'
})
}
export function getUserInfo(token) {
return request({ return request({
url: '/user/info', url: '/user/info',
method: 'get', method: 'get',
@ -27,3 +16,10 @@ export function getUserInfo(token) {
}) })
} }
export function logout() {
return request({
url: '/user/logout',
method: 'post'
})
}

View File

@ -83,7 +83,7 @@ export default {
this.$store.dispatch('toggleSideBar') this.$store.dispatch('toggleSideBar')
}, },
logout() { logout() {
this.$store.dispatch('LogOut').then(() => { this.$store.dispatch('Logout').then(() => {
location.reload()// In order to re-instantiate the vue-router object to avoid bugs location.reload()// In order to re-instantiate the vue-router object to avoid bugs
}) })
} }

View File

@ -29,18 +29,18 @@ router.beforeEach((to, from, next) => {
if (store.getters.roles.length === 0) { if (store.getters.roles.length === 0) {
// 判断当前用户是否已拉取完user_info信息 // 判断当前用户是否已拉取完user_info信息
store store
.dispatch('GetUserInfo') .dispatch('getInfo') // dispatch @/store/modules/user login getInfo
.then(res => { .then(res => {
// 拉取user_info // 拉取user_info
const roles = res.data.roles // note: roles must be a object array! such as: [{id: '1', name: 'editor'}, {id: '2', name: 'developer'}] const { roles } = res // note: roles must be a object array! such as: [{id: '1', name: 'editor'}, {id: '2', name: 'developer'}]
store.dispatch('GenerateRoutes', { roles }).then(accessRoutes => { store.dispatch('generateRoutes', { roles }).then(accessRoutes => {
// 根据roles权限生成可访问的路由表 // 根据roles权限生成可访问的路由表
router.addRoutes(accessRoutes) // 动态添加可访问路由表 router.addRoutes(accessRoutes) // 动态添加可访问路由表
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
}) })
}) })
.catch(err => { .catch(err => {
store.dispatch('FedLogOut').then(() => { store.dispatch('resetToken').then(() => {
Message.error(err) Message.error(err)
next({ path: '/' }) next({ path: '/' })
}) })

View File

@ -46,7 +46,7 @@ const permission = {
} }
}, },
actions: { actions: {
GenerateRoutes({ commit }, data) { generateRoutes({ commit }, data) {
return new Promise(resolve => { return new Promise(resolve => {
const { roles } = data const { roles } = data
let accessedRoutes let accessedRoutes

View File

@ -1,37 +1,22 @@
import { loginByUsername, logout, getUserInfo } from '@/api/login' import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth' import { getToken, setToken, removeToken } from '@/utils/auth'
const user = { const user = {
state: { state: {
user: '',
status: '',
code: '',
token: getToken(), token: getToken(),
name: '', name: '',
avatar: '', avatar: '',
introduction: '', introduction: '',
roles: [], roles: []
setting: {
articlePlatform: []
}
}, },
mutations: { mutations: {
SET_CODE: (state, code) => {
state.code = code
},
SET_TOKEN: (state, token) => { SET_TOKEN: (state, token) => {
state.token = token state.token = token
}, },
SET_INTRODUCTION: (state, introduction) => { SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction state.introduction = introduction
}, },
SET_SETTING: (state, setting) => {
state.setting = setting
},
SET_STATUS: (state, status) => {
state.status = status
},
SET_NAME: (state, name) => { SET_NAME: (state, name) => {
state.name = name state.name = name
}, },
@ -44,12 +29,12 @@ const user = {
}, },
actions: { actions: {
// 用户名登录 // user login
LoginByUsername({ commit }, userInfo) { login({ commit }, userInfo) {
const username = userInfo.username.trim() const { username, password } = userInfo
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(response => { login({ username: username.trim(), password: password }).then(response => {
const data = response.data const { data } = response
commit('SET_TOKEN', data.token) commit('SET_TOKEN', data.token)
setToken(response.data.token) setToken(response.data.token)
resolve() resolve()
@ -59,48 +44,36 @@ const user = {
}) })
}, },
// 获取用户信息 // get user info
GetUserInfo({ commit, state }) { getInfo({ commit, state }) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
getUserInfo(state.token).then(response => { getInfo(state.token).then(response => {
// 由于mockjs 不支持自定义状态码只能这样hack const { data } = response
if (!response.data) {
reject('Verification failed, please login again.')
}
const data = response.data
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 if (!data) {
commit('SET_ROLES', data.roles) reject('Verification failed, please Login again.')
} else { }
const { roles } = data
// roles must be a non-empty array
if (!roles || roles.length <= 0) {
reject('getInfo: roles must be a non-null array!') reject('getInfo: roles must be a non-null array!')
} }
commit('SET_ROLES', data.roles)
commit('SET_NAME', data.name) commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar) commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction) commit('SET_INTRODUCTION', data.introduction)
resolve(response) resolve(data)
}).catch(error => { }).catch(error => {
reject(error) reject(error)
}) })
}) })
}, },
// 第三方验证登录 // user logout
// LoginByThirdparty({ commit, state }, code) { Logout({ commit, state }) {
// 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) => { return new Promise((resolve, reject) => {
logout(state.token).then(() => { logout(state.token).then(() => {
commit('SET_TOKEN', '') commit('SET_TOKEN', '')
@ -113,27 +86,28 @@ const user = {
}) })
}, },
// 前端 登出 // remove token
FedLogOut({ commit }) { resetToken({ commit }) {
return new Promise(resolve => { return new Promise(resolve => {
commit('SET_TOKEN', '') commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken() removeToken()
resolve() resolve()
}) })
}, },
// 动态修改权限 // 动态修改权限
ChangeRoles({ commit, dispatch }, role) { changeRoles({ commit, dispatch }, role) {
return new Promise(resolve => { return new Promise(resolve => {
commit('SET_TOKEN', role) commit('SET_TOKEN', role)
setToken(role) setToken(role)
getUserInfo(role).then(response => { getInfo(role).then(response => {
const data = response.data const data = response.data
commit('SET_ROLES', data.roles) commit('SET_ROLES', data.roles)
commit('SET_NAME', data.name) commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar) commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction) commit('SET_INTRODUCTION', data.introduction)
dispatch('GenerateRoutes', data) // 动态修改权限后 重绘侧边菜单 dispatch('generateRoutes', data) // 动态修改权限后 重绘侧边菜单
resolve() resolve()
}) })
}) })

View File

@ -53,7 +53,7 @@ service.interceptors.response.use(
// cancelButtonText: '取消', // cancelButtonText: '取消',
// type: 'warning' // type: 'warning'
// }).then(() => { // }).then(() => {
// store.dispatch('FedLogOut').then(() => { // store.dispatch('resetToken').then(() => {
// location.reload() // 为了重新实例化vue-router对象 避免bug // location.reload() // 为了重新实例化vue-router对象 避免bug
// }) // })
// }) // })

View File

@ -1,10 +1,15 @@
<script> <script>
export default { export default {
name: 'AuthRedirect', name: 'Authredirect',
created() { created() {
const hash = window.location.search.slice(1) const hash = window.location.search.slice(1)
window.opener.location.href = window.location.origin + '/login#' + hash if (window.localStorage) {
window.close() window.localStorage.setItem('x-admin-oauth-code', hash)
window.close()
}
},
render: function(h) {
return h() // avoid warning message
} }
} }
</script> </script>

View File

@ -1,6 +1,7 @@
<template> <template>
<div class="login-container"> <div class="login-container">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
<div class="title-container"> <div class="title-container">
<h3 class="title"> <h3 class="title">
{{ $t('login.title') }} {{ $t('login.title') }}
@ -117,10 +118,10 @@ export default {
} }
}, },
created() { created() {
// window.addEventListener('hashchange', this.afterQRScan) // window.addEventListener('storage', this.afterQRScan)
}, },
destroyed() { destroyed() {
// window.removeEventListener('hashchange', this.afterQRScan) // window.removeEventListener('storage', this.afterQRScan)
}, },
methods: { methods: {
showPwd() { showPwd() {
@ -134,7 +135,8 @@ export default {
this.$refs.loginForm.validate(valid => { this.$refs.loginForm.validate(valid => {
if (valid) { if (valid) {
this.loading = true this.loading = true
this.$store.dispatch('LoginByUsername', this.loginForm).then(() => { // dispatch @/store/modules/user login action
this.$store.dispatch('login', this.loginForm).then(() => {
this.loading = false this.loading = false
this.$router.push({ path: this.redirect || '/' }) this.$router.push({ path: this.redirect || '/' })
}).catch(() => { }).catch(() => {
@ -145,74 +147,79 @@ export default {
return false return false
} }
}) })
},
afterQRScan() {
// const hash = window.location.hash.slice(1)
// const hashObj = getQueryObject(hash)
// const originUrl = window.location.origin
// history.replaceState({}, '', originUrl)
// const codeMap = {
// wechat: 'code',
// tencent: 'code'
// }
// const codeName = hashObj[codeMap[this.auth_type]]
// if (!codeName) {
// alert('')
// } else {
// this.$store.dispatch('LoginByThirdparty', codeName).then(() => {
// this.$router.push({ path: '/' })
// })
// }
} }
// afterQRScan() {
// if (e.key === 'x-admin-oauth-code') {
// const code = getQueryObject(e.newValue)
// const codeMap = {
// wechat: 'code',
// tencent: 'code'
// }
// const type = codeMap[this.auth_type]
// const codeName = code[type]
// if (codeName) {
// this.$store.dispatch('LoginByThirdparty', codeName).then(() => {
// this.$router.push({ path: this.redirect || '/' })
// })
// } else {
// alert('')
// }
// }
// }
} }
} }
</script> </script>
<style rel="stylesheet/scss" lang="scss"> <style rel="stylesheet/scss" lang="scss">
/* 修复input 背景不协调 和光标变色 */ /* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */ /* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg:#283443; $bg:#283443;
$light_gray:#eee; $light_gray:#eee;
$cursor: #fff; $cursor: #fff;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) { @supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input{ .login-container .el-input input {
color: $cursor; color: $cursor;
&::first-line {
color: $light_gray; &::first-line {
} color: $light_gray;
} }
} }
}
/* reset element-ui css */ /* reset element-ui css */
.login-container { .login-container {
.el-input { .el-input {
display: inline-block; display: inline-block;
height: 47px;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px; height: 47px;
width: 85%; caret-color: $cursor;
input {
background: transparent; &:-webkit-autofill {
border: 0px; -webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-appearance: none; -webkit-text-fill-color: $cursor !important;
border-radius: 0px;
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
caret-color: $cursor;
&:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px $bg inset !important;
-webkit-text-fill-color: $cursor !important;
}
} }
} }
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
} }
.el-form-item {
border: 1px solid rgba(255, 255, 255, 0.1);
background: rgba(0, 0, 0, 0.1);
border-radius: 5px;
color: #454545;
}
}
</style> </style>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss" scoped>
@ -225,6 +232,7 @@ $light_gray:#eee;
width: 100%; width: 100%;
background-color: $bg; background-color: $bg;
overflow: hidden; overflow: hidden;
.login-form { .login-form {
position: relative; position: relative;
width: 520px; width: 520px;
@ -233,16 +241,19 @@ $light_gray:#eee;
margin: 0 auto; margin: 0 auto;
overflow: hidden; overflow: hidden;
} }
.tips { .tips {
font-size: 14px; font-size: 14px;
color: #fff; color: #fff;
margin-bottom: 10px; margin-bottom: 10px;
span { span {
&:first-of-type { &:first-of-type {
margin-right: 16px; margin-right: 16px;
} }
} }
} }
.svg-container { .svg-container {
padding: 6px 5px 6px 15px; padding: 6px 5px 6px 15px;
color: $dark_gray; color: $dark_gray;
@ -250,8 +261,10 @@ $light_gray:#eee;
width: 30px; width: 30px;
display: inline-block; display: inline-block;
} }
.title-container { .title-container {
position: relative; position: relative;
.title { .title {
font-size: 26px; font-size: 26px;
color: $light_gray; color: $light_gray;
@ -259,15 +272,17 @@ $light_gray:#eee;
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;
} }
.set-language { .set-language {
color: #fff; color: #fff;
position: absolute; position: absolute;
top: 3px; top: 3px;
font-size:18px; font-size: 18px;
right: 0px; right: 0px;
cursor: pointer; cursor: pointer;
} }
} }
.show-pwd { .show-pwd {
position: absolute; position: absolute;
right: 10px; right: 10px;
@ -277,6 +292,7 @@ $light_gray:#eee;
cursor: pointer; cursor: pointer;
user-select: none; user-select: none;
} }
.thirdparty-button { .thirdparty-button {
position: absolute; position: absolute;
right: 0; right: 0;

View File

@ -22,7 +22,7 @@ export default {
return this.roles[0] return this.roles[0]
}, },
set(val) { set(val) {
this.$store.dispatch('ChangeRoles', val).then(() => { this.$store.dispatch('changeRoles', val).then(() => {
this.$emit('change') this.$emit('change')
}) })
} }