10 changed files with 453 additions and 15 deletions
-
3src/components/ParentView/index.vue
-
0src/layout/index.vue
-
4src/main.js
-
94src/router/index.js
-
5src/router/routers.js
-
6src/settings.js
-
28src/store/modules/api.js
-
86src/store/modules/permission.js
-
2src/utils/request.js
-
240src/views/login.vue
@ -0,0 +1,3 @@ |
|||
<template> |
|||
<router-view/> |
|||
</template> |
@ -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 |
@ -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 |
@ -0,0 +1,240 @@ |
|||
<template> |
|||
<div class="login" :style="'background-image:url('+ Background +');'"> |
|||
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" label-position="left" label-width="0px" class="login-form"> |
|||
<h3 class="title"> |
|||
阅行集成后台管理 |
|||
</h3> |
|||
<el-form-item prop="username"> |
|||
<el-input v-model="loginForm.username" type="text" auto-complete="off" placeholder="账号"> |
|||
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> |
|||
</el-input> |
|||
</el-form-item> |
|||
<el-form-item prop="password"> |
|||
<el-input v-model="loginForm.password" type="password" auto-complete="off" placeholder="密码" @keyup.enter.native="handleLogin"> |
|||
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /> |
|||
</el-input> |
|||
</el-form-item> |
|||
<el-form-item prop="code"> |
|||
<el-input v-model="loginForm.code" auto-complete="off" placeholder="验证码" style="width: 63%" @keyup.enter.native="handleLogin"> |
|||
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /> |
|||
</el-input> |
|||
<div class="login-code"> |
|||
<img :src="codeUrl" @click="getCode"> |
|||
</div> |
|||
</el-form-item> |
|||
<el-checkbox v-model="loginForm.rememberMe" style="margin:0 0 25px 0;"> |
|||
记住我 |
|||
</el-checkbox> |
|||
<el-form-item style="width:100%;"> |
|||
<el-button :loading="loading" size="medium" type="primary" style="width:100%;" @click.native.prevent="handleLogin"> |
|||
<span v-if="!loading">登 录</span> |
|||
<span v-else>登 录 中...</span> |
|||
</el-button> |
|||
</el-form-item> |
|||
</el-form> |
|||
<!-- 底部 --> |
|||
<!-- <div v-if="$store.state.settings.showFooter" id="el-login-footer"> |
|||
<span v-html="$store.state.settings.footerTxt" /> |
|||
<span> ⋅ </span> |
|||
<a href="https://beian.miit.gov.cn/#/Integrated/index" target="_blank">{{ $store.state.settings.caseNumber }}</a> |
|||
</div> --> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
import { encrypt } from "@/utils/rsaEncrypt"; |
|||
import Config from "@/settings"; |
|||
import Cookies from "js-cookie"; |
|||
import Background from "@/assets/images/background.jpg"; |
|||
import { getCodeImg } from '@/api/login' |
|||
|
|||
export default { |
|||
//输出模块名称 |
|||
name: 'Login', |
|||
data() { |
|||
return { |
|||
//背景图 |
|||
Background: Background, |
|||
//登录验证码 |
|||
codeUrl: '', |
|||
//通行证 |
|||
cookiePass: '', |
|||
//默认登录信息--测试用 |
|||
loginForm: { |
|||
username: 'admin', |
|||
password: '123456', |
|||
rememberMe: false, |
|||
code: '', |
|||
uuid: '', |
|||
}, |
|||
//登录规则 |
|||
loginRules: { |
|||
username: [ |
|||
{ required: true, trigger: 'blur', message: '用户名不能为空' }, |
|||
], |
|||
password: [ |
|||
{ required: true, trigger: 'blur', message: '密码不能为空' }, |
|||
], |
|||
code: [ |
|||
{ required: true, trigger: 'change', message: '验证码不能为空' }, |
|||
], |
|||
}, |
|||
//加载状态是否显示 |
|||
loading: false, |
|||
//跳转定向 |
|||
redirect: undefined |
|||
}; |
|||
}, |
|||
watch: { |
|||
//监听路由变化 |
|||
$route: { |
|||
handler: function (route) { |
|||
this.redirect = route.query && route.query.redirect; |
|||
}, |
|||
//立即执行handler |
|||
immediate: true, |
|||
}, |
|||
}, |
|||
// 使用钩子初始化获取信息 |
|||
created() { |
|||
//获取验证码 |
|||
this.getCode(); |
|||
//获取用户名密码等 Cookie |
|||
this.getCookie(); |
|||
// token过期提示 |
|||
this.point(); |
|||
}, |
|||
methods: { |
|||
//获取验证码方法 |
|||
getCode() { |
|||
getCodeImg().then((res) => { |
|||
this.codeUrl = res.img; |
|||
this.loginForm.uuid = res.uuid; |
|||
}); |
|||
}, |
|||
//获取Cookie |
|||
getCookie() { |
|||
const username = Cookies.get('username'); |
|||
let password = Cookies.get('password'); |
|||
const rememberMe = Cookies.get('rememberMe'); |
|||
// 保存cookie里面的加密后的密码 |
|||
this.cookiePass = password === undefined ? '' : password; |
|||
password = password === undefined ? this.loginForm.password : password; |
|||
this.loginForm = { |
|||
username: username === undefined ? this.loginForm.username : username, |
|||
password: password, |
|||
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe), |
|||
code: '', |
|||
}; |
|||
}, |
|||
handleLogin() { |
|||
this.$refs.loginForm.validate((valid) => { |
|||
// 获取登录信息 |
|||
const user = { |
|||
username: this.loginForm.username, |
|||
password: this.loginForm.password, |
|||
rememberMe: this.loginForm.rememberMe, |
|||
code: this.loginForm.code, |
|||
uuid: this.loginForm.uuid, |
|||
}; |
|||
//如果cookie通行证不匹配 |
|||
if (user.password !== this.cookiePass) { |
|||
//把密码进行加密处理 |
|||
user.password = encrypt(user.password); |
|||
} |
|||
if (valid) { |
|||
this.loading = true; |
|||
if (user.rememberMe) { |
|||
Cookies.set('username', user.username, { |
|||
expires: Config.passCookieExpires, |
|||
}); |
|||
Cookies.set('password', user.password, { |
|||
expires: Config.passCookieExpires, |
|||
}); |
|||
Cookies.set('rememberMe', user.rememberMe, { |
|||
expires: Config.passCookieExpires, |
|||
}); |
|||
} else { |
|||
Cookies.remove('username'); |
|||
Cookies.remove('password'); |
|||
Cookies.remove('rememberMe'); |
|||
} |
|||
this.$store |
|||
.dispatch('Login', user) |
|||
.then(() => { |
|||
this.loading = false; |
|||
this.$router.push({ path: this.redirect || '/' }); |
|||
}) |
|||
.catch(() => { |
|||
this.loading = false; |
|||
this.getCode(); |
|||
}); |
|||
} else { |
|||
console.log("提交错误!!"); |
|||
return false; |
|||
} |
|||
}); |
|||
}, |
|||
point() { |
|||
const point = Cookies.get('point') !== undefined; |
|||
if (point) { |
|||
this.$notify({ |
|||
title: "提示", |
|||
message: "当前登录状态已过期,请重新登录!", |
|||
type: "warning", |
|||
duration: 5000, |
|||
}); |
|||
Cookies.remove("point"); |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style rel="stylesheet/scss" lang="scss"> |
|||
.login { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
height: 100%; |
|||
background-size: cover; |
|||
} |
|||
.title { |
|||
margin: 0 auto 30px auto; |
|||
text-align: center; |
|||
color: #707070; |
|||
} |
|||
|
|||
.login-form { |
|||
border-radius: 6px; |
|||
background: #ffffff; |
|||
width: 385px; |
|||
padding: 25px 25px 5px 25px; |
|||
.el-input { |
|||
height: 38px; |
|||
input { |
|||
height: 38px; |
|||
} |
|||
} |
|||
.input-icon { |
|||
height: 39px; |
|||
width: 14px; |
|||
margin-left: 2px; |
|||
} |
|||
} |
|||
.login-tip { |
|||
font-size: 13px; |
|||
text-align: center; |
|||
color: #bfbfbf; |
|||
} |
|||
.login-code { |
|||
width: 33%; |
|||
display: inline-block; |
|||
height: 38px; |
|||
float: right; |
|||
img { |
|||
cursor: pointer; |
|||
vertical-align: middle; |
|||
} |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue