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',
reviewer: '@first',
title: '@title(5, 10)',
content_short: '我是测试数据',
content_short: 'mock data',
content: baseContent,
forecast: '@float(0, 100, 2, 2)',
importance: '@integer(1, 3)',

View File

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

View File

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

View File

@ -1,48 +1,57 @@
const userMap = {
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
const users = {
'admin-token': {
roles: ['admin'],
token: 'admin',
introduction: '我是超级管理员',
introduction: 'I am a super administrator',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
editor: {
'editor-token': {
roles: ['editor'],
token: 'editor',
introduction: '我是编辑',
introduction: 'I am an editor',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
export default [
// user login
{
url: '/login/login',
url: '/user/login',
type: 'post',
response: config => {
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',
response: _ => {
return {
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'
export function loginByUsername(username, password) {
const data = {
username,
password
}
export function login(data) {
return request({
url: '/login/login',
url: '/user/login',
method: 'post',
data
})
}
export function logout() {
return request({
url: '/login/logout',
method: 'post'
})
}
export function getUserInfo(token) {
export function getInfo(token) {
return request({
url: '/user/info',
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')
},
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
})
}

View File

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

View File

@ -46,7 +46,7 @@ const permission = {
}
},
actions: {
GenerateRoutes({ commit }, data) {
generateRoutes({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
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'
const user = {
state: {
user: '',
status: '',
code: '',
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: [],
setting: {
articlePlatform: []
}
roles: []
},
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
},
@ -44,12 +29,12 @@ const user = {
},
actions: {
// 用户名登录
LoginByUsername({ commit }, userInfo) {
const username = userInfo.username.trim()
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
return new Promise((resolve, reject) => {
loginByUsername(username, userInfo.password).then(response => {
const data = response.data
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(response.data.token)
resolve()
@ -59,48 +44,36 @@ const user = {
})
},
// 获取用户信息
GetUserInfo({ commit, state }) {
// get user info
getInfo({ 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
getInfo(state.token).then(response => {
const { data } = response
if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
commit('SET_ROLES', data.roles)
} else {
if (!data) {
reject('Verification failed, please Login again.')
}
const { roles } = 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', data.roles)
commit('SET_NAME', data.name)
commit('SET_AVATAR', data.avatar)
commit('SET_INTRODUCTION', data.introduction)
resolve(response)
resolve(data)
}).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 }) {
// user logout
Logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')
@ -113,27 +86,28 @@ const user = {
})
},
// 前端 登出
FedLogOut({ commit }) {
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resolve()
})
},
// 动态修改权限
ChangeRoles({ commit, dispatch }, role) {
changeRoles({ commit, dispatch }, role) {
return new Promise(resolve => {
commit('SET_TOKEN', role)
setToken(role)
getUserInfo(role).then(response => {
getInfo(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) // 动态修改权限后 重绘侧边菜单
dispatch('generateRoutes', data) // 动态修改权限后 重绘侧边菜单
resolve()
})
})

View File

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

View File

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

View File

@ -1,6 +1,7 @@
<template>
<div class="login-container">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left">
<div class="title-container">
<h3 class="title">
{{ $t('login.title') }}
@ -117,10 +118,10 @@ export default {
}
},
created() {
// window.addEventListener('hashchange', this.afterQRScan)
// window.addEventListener('storage', this.afterQRScan)
},
destroyed() {
// window.removeEventListener('hashchange', this.afterQRScan)
// window.removeEventListener('storage', this.afterQRScan)
},
methods: {
showPwd() {
@ -134,7 +135,8 @@ export default {
this.$refs.loginForm.validate(valid => {
if (valid) {
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.$router.push({ path: this.redirect || '/' })
}).catch(() => {
@ -145,74 +147,79 @@ export default {
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>
<style rel="stylesheet/scss" lang="scss">
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg:#283443;
$light_gray:#eee;
$cursor: #fff;
$bg:#283443;
$light_gray:#eee;
$cursor: #fff;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input{
color: $cursor;
&::first-line {
color: $light_gray;
}
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
&::first-line {
color: $light_gray;
}
}
}
/* reset element-ui css */
.login-container {
.el-input {
display: inline-block;
/* reset element-ui css */
.login-container {
.el-input {
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;
width: 85%;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
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;
}
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 rel="stylesheet/scss" lang="scss" scoped>
@ -225,6 +232,7 @@ $light_gray:#eee;
width: 100%;
background-color: $bg;
overflow: hidden;
.login-form {
position: relative;
width: 520px;
@ -233,16 +241,19 @@ $light_gray:#eee;
margin: 0 auto;
overflow: hidden;
}
.tips {
font-size: 14px;
color: #fff;
margin-bottom: 10px;
span {
&:first-of-type {
margin-right: 16px;
}
}
}
.svg-container {
padding: 6px 5px 6px 15px;
color: $dark_gray;
@ -250,8 +261,10 @@ $light_gray:#eee;
width: 30px;
display: inline-block;
}
.title-container {
position: relative;
.title {
font-size: 26px;
color: $light_gray;
@ -259,15 +272,17 @@ $light_gray:#eee;
text-align: center;
font-weight: bold;
}
.set-language {
color: #fff;
position: absolute;
top: 3px;
font-size:18px;
font-size: 18px;
right: 0px;
cursor: pointer;
}
}
.show-pwd {
position: absolute;
right: 10px;
@ -277,6 +292,7 @@ $light_gray:#eee;
cursor: pointer;
user-select: none;
}
.thirdparty-button {
position: absolute;
right: 0;

View File

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