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.

421 lines
10 KiB

2 years ago
<template>
<div class="login-container">
1 year ago
<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>-->
2 years ago
1 year ago
<img class="title-img" src="~@/assets/login/title.png" alt="">
2 years ago
<el-form size="small" ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on"
2 years ago
label-position="left">
<div class="title-container">
1 year ago
<h3 class="title">欢迎登录</h3>
2 years ago
</div>
<el-form-item prop="username">
1 year ago
<div class="form-item">
<span class="svg-container">
2 years ago
<svg-icon icon-class="user" />
</span>
1 year ago
<el-input ref="username" v-model="loginForm.username" placeholder="请输入登录名" name="username" type="text"
tabindex="1" auto-complete="on" />
</div>
2 years ago
</el-form-item>
<el-form-item prop="password">
1 year ago
<div class="form-item">
<span class="svg-container">
2 years ago
<svg-icon icon-class="password" />
</span>
1 year ago
<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>
2 years ago
</el-form-item>
2 years ago
<el-form-item prop="code">
1 year ago
<div class="form-item">
2 years ago
<span class="svg-container">
1 year ago
<svg-icon icon-class="message" />
</span>
2 years ago
<el-input ref="username" v-model="loginForm.code" placeholder="请输入验证码" name="username" type="text"
2 years ago
tabindex="1" auto-complete="on" />
1 year ago
<el-button class="msg-btn" :loading="msgLoading" type="primary" size="small" :disabled="isVer" @click="sendSms">{{ isVer ? (''+verTime+'') : '' }}</el-button>
2 years ago
</div>
</el-form-item>
1 year ago
<el-button :loading="loading" type="primary" class="login-btn"
2 years ago
@click.native.prevent="handleLogin">登录</el-button>
</el-form>
<footer class="copyright">
版权所有无锡市交通产业集团有限公司
</footer>
2 years ago
</div>
</template>
<script>
import {
validUsername
} from '@/utils/validate'
2 years ago
import { login, getInfo } from "@/api/user";
import { sendSms, checkSms } from "@/api/common"
2 years ago
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: '',
2 years ago
code: ''
2 years ago
},
loginRules: {
username: [{
required: true,
trigger: 'blur',
validator: validateUsername
}],
password: [{
required: true,
trigger: 'blur',
validator: validatePassword
}],
1 year ago
code: [
{
2 years ago
required: true,
trigger: 'blur',
message: '请输入验证码',
validator: (rule, value, callback) => {
if (value.length !== 4) {
1 year ago
callback(new Error('验证码输入错误'))
2 years ago
} else {
callback()
}
}
1 year ago
}
]
2 years ago
},
2 years ago
msgLoading: false,
2 years ago
loading: false,
passwordType: 'password',
2 years ago
redirect: undefined,
verTime: 60,
isVer: false,
temp: {
mobile: "",
token: ""
}
2 years ago
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
created() {
this.title = defaultSettings.title;
},
methods: {
2 years ago
async sendSms () {
if (this.isVer) return;
1 year ago
if (this.loginForm.username) {
2 years ago
this.msgLoading = true;
try {
await sendSms({
1 year ago
username: this.loginForm.username
2 years ago
})
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({
1 year ago
message: '请输入登录名',
2 years ago
type: 'warning'
})
}
3 years ago
},
2 years ago
showPwd() {
if (this.passwordType === 'password') {
this.passwordType = ''
} else {
this.passwordType = 'password'
}
this.$nextTick(() => {
this.$refs.password.focus()
})
},
//处理登录
2 years ago
async handleLogin() {
this.$refs.loginForm.validate(async(valid) => {
2 years ago
if (valid) {
1 year ago
2 years ago
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 */
1 year ago
2 years ago
.login-container {
.el-input {
1 year ago
flex: 1;
2 years ago
display: inline-block;
input {
background: transparent;
border: 0px;
-webkit-appearance: none;
border-radius: 0px;
1 year ago
padding: 4px 5px 4px 15px;
2 years ago
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;
1 year ago
.build-img {
position: absolute;
width: 46.5vw;
1 year ago
object-fit: contain;
top: 26.8%;
left: 4%;
1 year ago
}
.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;
}
2 years ago
.login-container {
1 year ago
height: 100%;
2 years ago
width: 100%;
1 year ago
background: url("~@/assets/login/bkg.png") no-repeat;
background-size: cover;
2 years ago
overflow: hidden;
.login-form {
position: relative;
1 year ago
width: 28.7vw;
margin: 9.81vh 10.2vw 0 auto;
2 years ago
overflow: hidden;
1 year ago
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);
2 years ago
}
.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;
1 year ago
margin-bottom: 2vw;
2 years ago
.title {
text-align: center;
1 year ago
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;
}
2 years ago
}
}
.show-pwd {
position: absolute;
right: 8%;
1 year ago
top: 50%;
transform: translate(0, -50%);
2 years ago
font-size: 16px;
color: $dark_gray;
cursor: pointer;
user-select: none;
}
1 year ago
.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;
}
.copyright {
width: 100%;
text-align: center;
color: #fff;
line-height: 16px;
font-size: 16px;
position: absolute;
left: 0;
bottom: 6vh;
}
1 year ago
@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%);
}
2 years ago
}
4 years ago
</style>