You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

335 lines
8.7 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="login-container">
<vue-particles color="#ffffff" :particleOpacity="0.7" :particlesNumber="80" shapeType="circle" :particleSize="4"
linesColor="#ffffff" :linesWidth="1" :lineLinked="true" :lineOpacity="0.4" :linesDistance="150" :moveSpeed="3"
:hoverEffect="true" hoverMode="grab" :clickEffect="true" clickMode="push"> </vue-particles>
<el-form size="small" ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
label-position="left">
<div class="title-container">
<h3 class="title">{{title}}</h3>
</div>
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<el-input ref="username" v-model="loginForm.username" placeholder="请输入登录名" name="username" type="text"
tabindex="1" auto-complete="on" />
</el-form-item>
<el-form-item prop="password">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input :key="passwordType" ref="password" v-model="loginForm.password" :type="passwordType"
placeholder="请输入密码" name="password" tabindex="2" auto-complete="on" @keyup.enter.native="handleLogin" />
<span class="show-pwd" @click="showPwd">
<svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
</span>
</el-form-item>
<el-form-item prop="code">
<div style="display: flex;">
<span class="svg-container">
<svg-icon icon-class="message" />
</span>
<el-input ref="username" v-model="loginForm.code" placeholder="请输入验证码" name="username" type="text"
tabindex="1" auto-complete="on" />
<el-button :loading="msgLoading" type="primary" size="small" :disabled="isVer" @click="sendSms">发送验证{{ isVer ? (''+verTime+'') : '' }}</el-button>
</div>
</el-form-item>
<el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;"
@click.native.prevent="handleLogin">登录</el-button>
</el-form>
</div>
</template>
<script>
import {
validUsername
} from '@/utils/validate'
import { login, getInfo } from "@/api/user";
import { sendSms, checkSms } from "@/api/common"
const defaultSettings = require('../../../src/settings.js')
export default {
name: 'Login',
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error('请正确输入登录名'))
} else {
callback()
}
}
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('密码输入错误'))
} else {
callback()
}
}
return {
title: "",
loginForm: {
username: '',
password: '',
code: ''
},
loginRules: {
username: [{
required: true,
trigger: 'blur',
validator: validateUsername
}],
password: [{
required: true,
trigger: 'blur',
validator: validatePassword
}],
code: [{
required: true,
trigger: 'blur',
message: '请输入验证码',
validator: (rule, value, callback) => {
if (this.loginForm.username === 'admin') {
callback()
return
}
if (value.length !== 4) {
callback(new Error('密码输入错误'))
} else {
callback()
}
}
}]
},
msgLoading: false,
loading: false,
passwordType: 'password',
redirect: undefined,
verTime: 60,
isVer: false,
temp: {
mobile: "",
token: ""
}
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
created() {
this.title = defaultSettings.title;
},
methods: {
async sendSms () {
if (this.isVer) return;
if (this.loginForm.username && this.loginForm.password) {
this.msgLoading = true;
try {
const { access_token } = (await login(this.loginForm))
const { mobile } = (await getInfo(access_token))
this.temp.mobile = mobile;
this.temp.token = access_token;
await sendSms({
mobile,
token: access_token
})
this.isVer = true;
this.verTime = 60;
this.$message({
message: '验证码已发送',
type:'success'
})
let timer = setInterval(() => {
this.verTime--;
if (this.verTime <= 0) {
this.isVer = false;
clearInterval(timer);
}
}, 1000);
this.msgLoading = false;
} catch (e) {
this.msgLoading = false;
}
} else {
this.$message({
message: '请输入登录名和密码',
type: 'warning'
})
}
},
showPwd() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
this.$refs.password.focus()
})
},
//处理登录
async handleLogin() {
this.$refs.loginForm.validate(async(valid) => {
if (valid) {
if (this.loginForm.username !== 'admin') {
await checkSms({
mobile: this.temp.mobile,
token: this.temp.token,
code: this.loginForm.code
})
}
this.loading = true
this.$store.dispatch('user/login', this.loginForm).then(() => {
this.$router.push({
path: this.redirect || '/'
})
this.loading = false
}).catch(() => {
this.loading = false
})
} else {
console.log('error submit!!')
return false
}
})
}
}
}
</script>
<style lang="scss">
#particles-js {
width: 100%;
height: 99%;
position: absolute;
}
/* input */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg:#122583;
$light_gray:#122583;
$cursor: #122583;
@supports (-webkit-mask: none) and (not (cater-color: $cursor)) {
.login-container .el-input input {
color: $cursor;
}
}
/* 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;
caret-color: $cursor;
&:-webkit-autofill {
//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;
}
}
</style>
<style lang="scss" scoped>
$bg:#122583;
$dark_gray:#122583;
$light_gray:#122583;
.login-container {
min-height: 100%;
width: 100%;
//background-color: $bg;
background: url("../../assets/bg.jpg") no-repeat;
overflow: hidden;
.login-form {
position: relative;
width: 520px;
max-width: 100%;
padding: 20px 35px 0;
margin: 160px auto;
overflow: hidden;
background-color: #fff;
}
.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;
vertical-align: middle;
width: 30px;
display: inline-block;
}
.title-container {
position: relative;
.title {
font-size: 26px;
color: $light_gray;
margin: 0px auto 40px auto;
text-align: center;
font-weight: bold;
}
}
.show-pwd {
position: absolute;
right: 10px;
top: 7px;
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
}
</style>