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.

405 lines
10 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">
<img class="build-img" src="~@/assets/login/build.png" alt="">
<!-- <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>-->
<img class="title-img" src="~@/assets/login/title.png" alt="">
<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">欢迎登录</h3>
</div>
<el-form-item prop="username">
<div class="form-item">
<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" />
</div>
</el-form-item>
<el-form-item prop="password">
<div class="form-item">
<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>
</div>
</el-form-item>
<el-form-item prop="code">
<div class="form-item">
<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 class="msg-btn" :loading="msgLoading" type="primary" size="small" :disabled="isVer" @click="sendSms">发送验证{{ isVer ? (''+verTime+'') : '' }}</el-button>
</div>
</el-form-item>
<el-button :loading="loading" type="primary" class="login-btn"
@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 (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.msgLoading = true;
try {
await sendSms({
username: this.loginForm.username
})
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) {
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 {
flex: 1;
display: inline-block;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
padding: 4px 5px 4px 15px;
color: $light_gray;
caret-color: $cursor;
&:-webkit-autofill {
//box-shadow: 0 0 0px 1000px $bg inset !important;
//-webkit-text-fill-color: $cursor !important;
}
}
}
}
</style>
<style lang="scss" scoped>
$bg:#122583;
$dark_gray:#122583;
$light_gray:#122583;
.build-img {
position: absolute;
width: 36.5vw;
object-fit: contain;
top: 27.3%;
left: 10.2%;
}
.title-img {
display: block;
width: 44.64vw;
object-fit: contain;
margin: 16.11vh auto 0;
}
.form-item {
height: 3vw;
width: 86.4%;
margin: auto;
border-radius: 8px;
background-color: #f4f4f4;
filter: drop-shadow(0 0 1px #cdcdcd);
display: flex;
align-items: center;
}
.login-container {
height: 100%;
width: 100%;
background: url("~@/assets/login/bkg.png") no-repeat;
background-size: cover;
overflow: hidden;
.login-form {
position: relative;
width: 28.7vw;
margin: 9.81vh 10.2vw 0 auto;
overflow: hidden;
border-radius: 10px;
box-shadow: inset 0 0 4px rgb(255,255,255,0.8);
filter: drop-shadow(0 0 7px rgba(0,0,0,0.2));
background-color: rgba(255,255,255,0.2);
}
.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;
margin-bottom: 2vw;
.title {
text-align: center;
font-size: 1.7vw;
letter-spacing: 4px;
color: #ffffff;
padding: 1.41vw 0 1.2vw;
position: relative;
&::after {
content: "";
width: 100%;
height: 1px;
background: linear-gradient(to right, #fff0 20%, #fff, #fff0 80%);
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
}
}
.show-pwd {
position: absolute;
right: 10%;
top: 50%;
transform: translate(0, -50%);
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
.msg-btn {
border-radius: 0 8px 8px 0;
height: 100%;
background-image: linear-gradient(90deg, #1d57da 0%, #1d57da 0%, #4185c5 100%);
}
.login-btn {
width: 86.4%;
height: 3vw;
border-radius: 8px;
padding: 0;
background-image: linear-gradient(90deg, #1d57da 0%, #1d57da 0%, #05a658 100%);
display: block;
margin: auto auto 3.2vw;
font-size: 1.21vw;
letter-spacing: 3px;
color: #ffffff;
}
}
::v-deep .el-form-item--small.el-form-item {
margin-bottom: 1.3vw;
}
@media (max-width: 960px) {
.title-img {
display: none;
}
.login-container .login-form {
width: 90%;
margin: auto;
position: relative;
top: 50%;
transform: translateY(-50%);
}
.login-container .title-container .title {
font-size: 15px;
}
.form-item {
height: 40px;
margin-bottom: 10px;
}
.login-container .login-btn {
height: 40px;
font-size: 14px;
}
::v-deep .el-form-item__error {
transform: translate(-20px,-76%);
}
}
</style>