f745e1dd by 任超

feat:登录

1 parent 81f92c0a
......@@ -17,7 +17,6 @@ import router from './router'
import _ from 'lodash'
import './icons' // icon
import './permission' // permission control
import * as filters from './filters' // global filters
Vue.use(lbTable);
......
......@@ -21,16 +21,6 @@ export const constantRoutes = [
]
},
{
path: '/login',
component: () => import('@/views/login/login'),
hidden: true
},
{
path: '/auth-redirect',
component: () => import('@/views/login/auth-redirect'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/home',
......
<script>
export default {
name: 'AuthRedirect',
created() {
const hash = window.location.search.slice(1)
if (window.localStorage) {
window.localStorage.setItem('x-admin-oauth-code', hash)
window.close()
}
},
render: function(h) {
return h() // avoid warning message
}
}
</script>
<template>
<div class="jc-component__range">
<div v-loading="loading" class="jc-range" :class="rangeStatus ? 'success' : ''">
<i @mousedown="rangeMove" :class="rangeStatus ? successIcon : startIcon"></i>
{{ rangeStatus ? successText : startText }}
</div>
</div>
</template>
<script>
import * as login from '@/api/login'
export default {
props: {
// 成功之后的函数
successFun: {
type: Function,
},
//成功图标
successIcon: {
type: String,
default: 'el-icon-check',
},
//成功文字
successText: {
type: String,
default: '验证成功',
},
//开始的图标
startIcon: {
type: String,
default: 'el-icon-right',
},
//开始的文字
startText: {
type: String,
default: '请按住滑块,拖动到最右边',
},
//失败之后的函数
errorFun: {
type: Function,
},
//或者用值来进行监听
status: {
type: String,
},
},
data () {
return {
loading: false,
disX: 0,
rangeStatus: false,
str: {},
}
},
methods: {
moveFn (e) {
let ele = e.target
ele.style.transition = '.5s all'
ele.style.transform = 'translateX(0)'
this.rangeStatus = false
// 执行成功的函数
this.errorFun()
},
//滑块移动
rangeMove (e) {
this.str = e
let ele = e.target
let startX = e.clientX
let eleWidth = ele.offsetWidth
let parentWidth = ele.parentElement.offsetWidth
let MaxX = parentWidth - eleWidth
if (this.rangeStatus) {
//不运行
return false
}
document.onmousemove = (e) => {
let endX = e.clientX
this.disX = endX - startX
if (this.disX <= 0) {
this.disX = 0
}
if (this.disX >= MaxX - eleWidth) {
//减去滑块的宽度,体验效果更好
this.disX = MaxX
}
ele.style.transition = '.1s all'
ele.style.background = 'red!important'
ele.style.transform = 'translateX(' + this.disX + 'px)'
e.preventDefault()
}
document.onmouseup = async () => {
if (this.disX !== MaxX) {
ele.style.transition = '.5s all'
ele.style.transform = 'translateX(0)'
// 执行成功的函数
this.errorFun && this.errorFun()
}
else {
this.successFun && this.successFun()
this.rangeStatus = true
this.loading = true
if (this.status) {
this.$parent[this.status] = true
}
}
document.onmousemove = null
document.onmouseup = null
}
},
},
}
</script>
<style lang="scss" scoped>
@mixin jc-flex {
display: flex;
justify-content: center;
align-items: center;
}
.jc-component__range {
.jc-range {
background-color: #F7FAFE;
border: 1px solid #D8E0E9;
position: relative;
transition: 1s all;
user-select: none;
color: #9B9B9B;
display: flex;
// justify-content: center;
padding-left: 50px;
align-items: center;
height: 40px;
/*no*/
&.success {
background-color: #D2F5EF;
color: #4caf50;
border: 1px solid #99D5D0;
font-size: 16px;
justify-content: center;
padding-left: 0px;
i {
color: #ffffff;
background-color: #51CCBF;
}
}
i {
position: absolute;
left: 0;
width: 38px;
/*no*/
height: 40px;
background-color: #fff;
border: 1px solid #d8d8d8;
cursor: pointer;
font-size: 14px;
color: #829ABA;
@include jc-flex;
}
}
}
</style>
<style lang="scss" scoped>
/deep/.el-loading-spinner {
top: 62%;
.circular {
height: 35px !important;
width: 30px !important;
}
}
/deep/.el-loading-mask {
background-color: rgba(255, 255, 255, 1);
}
</style>
\ No newline at end of file
<template>
<div class="login">
<div class="login-header-title">
<img src="./img/login-title.png">
</div>
<div class="login-content_code">
<div class="hidden-bos">
<img src='./img/72054ab975174650a84d0a975de6712.png' @click.stop="Codeclick('2')" alt="">
</div>
<div class="login-form">
<h3 class="login-title ">
<p>{{ activeName }}</p>
</h3>
<el-form :model="ruleForm" :rules="rules" size="large" ref="ruleForm">
<el-form-item prop="username">
<el-input type="text" placeholder="请输入账号/手机号" v-model="ruleForm.username">
<svg-icon slot="prefix" icon-class="username" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input type="password" placeholder="请输入登录密码" v-model="ruleForm.password">
<svg-icon slot="prefix" icon-class="password" />
</el-input>
</el-form-item>
<el-form-item prop="code">
<JcRange ref='jcrangeRef' :successFun="verificate_sucess" :errorFun="verificate_error"></JcRange>
</el-form-item>
<el-form-item class="login-button-form">
<el-button type="primary" class="submit-button" @click="submitForm('ruleForm')">登录
</el-button>
</el-form-item>
</el-form>
</div>
</div>
<div class="login-footer">
Copyright © 2021-2025闽ICP备20013799号-2
</div>
</div>
</template>
<script>
import * as login from '@/api/login'
import JcRange from './components/JcRange'
import dialogBox from '@/components/dialogBox/index';
export default {
components: {
JcRange,
dialogBox
},
data () {
return {
activeName: '登录',
ruleForm: {
username: '',
password: '',
location: '',
code: ''
},
rules: {
username: [
{ required: true, message: '请输入账号/手机号', trigger: 'blur' },
],
password: [
{
required: true,
message: '请输入登录密码',
trigger: 'blur'
}
],
code: [
{
required: true,
message: '请滑动完成验证',
trigger: 'blur'
}
]
},
loading: false,
redirect: undefined,
otherQuery: {}
}
},
watch: {
$route: {
handler: function (route) {
const query = route.query
if (query) {
this.redirect = query.redirect
this.otherQuery = this.getOtherQuery(query)
}
},
immediate: true
},
},
methods: {
async getcode () {
try {
const res = await login.verifyCode()
this.ruleForm.code = res
if (this.ruleForm.code !== '') {
this.$refs.jcrangeRef.loading = false
}
} catch (error) {
this.$refs.jcrangeRef.loading = true
this.$message.error('获取验证码失败')
}
},
handleCode () {
this.getcode()
},
submitForm (formName) {
this.$refs[formName].validate(async valid => {
if (valid) {
this.$store.dispatch('user/login', this.ruleForm).then((res) => {
this.$router.push({
path: this.redirect || '/',
query: this.otherQuery
})
}).catch(e => {
this.$refs.jcrangeRef.disX = 0
this.$refs.jcrangeRef.moveFn(this.$refs.jcrangeRef.str)
})
} else {
return false
}
})
},
getOtherQuery (query) {
return Object.keys(query).reduce((acc, cur) => {
if (cur !== 'redirect') {
acc[cur] = query[cur]
}
return acc
}, {})
},
// 验证码
verificate_sucess () {
this.getcode()
},
verificate_error () {
this.ruleForm.code = ''
}
}
}
</script>
<style lang="scss" scoped>
.login {
width: 100%;
height: 100%;
background: url("./img/xinBg.png") no-repeat;
background-size: 100% auto;
display: flex;
align-items: center;
flex-direction: column;
position: relative;
.login-header-title {
width: 40%;
margin: 5% 0 40px 0;
min-height: 65px;
img {
width: 100%;
}
}
.login-content_code {
width: 25%;
background-color: #ffffff;
box-shadow: 0px 0px 30px 0px rgba(130, 154, 186, 0.2);
border-radius: 8px;
background-repeat: no-repeat;
background-position: top right;
position: relative;
.hidden-box {
text-align: right;
cursor: pointer;
position: absolute;
right: 0;
top: 0;
img {
width: 45%;
}
}
.hidden-bos {
text-align: right;
cursor: pointer;
position: absolute;
right: 0;
top: 0;
img {
width: 45%;
}
}
.login-form {
width: 100%;
min-height: 385px;
padding: 20px 30px 0 30px;
box-sizing: border-box;
.code-item {
display: flex;
align-items: center;
height: 40px;
width: 100%;
img {
width: 100px;
height: 40px;
float: right;
cursor: pointer;
}
}
/deep/.el-input__prefix {
display: flex;
align-items: center;
justify-content: center;
margin-left: 10px;
}
/deep/.el-input__prefix:after {
content: "";
position: absolute;
right: -9px;
top: 13px;
height: 14px;
border-right: 1px solid #d9d9d9;
}
/deep/.el-input__inner {
padding-left: 50px;
}
.code-input {
position: relative;
/deep/.el-input__inner {
border-right: none;
}
.verification-code {
width: 96px;
height: 31px;
}
/deep/.el-input-group__append {
border-left: none;
background: none;
}
}
.login-title {
margin-bottom: 20px;
text-align: center;
p {
font-size: 20px;
color: #8a8a8a;
width: 25%;
margin: 0 auto;
border-bottom: 2px solid #0f93f6;
padding-bottom: 10px;
}
}
}
}
}
</style>
\ No newline at end of file