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