web-base-admin/src/views/login/index.vue

508 lines
11 KiB
Vue
Raw Normal View History

2025-03-23 09:18:42 +08:00
<template>
<div class="login-container">
<div class="top_item">
<div class="title_no">全球一体化系统管理平台</div>
<dv-decoration-5
:color="['#4278a3', '#4278a3']"
style="width: 100%; height: 100px"
/>
</div>
<!-- <div class="qiu">
<img src="@/assets/images/globel.gif"
alt="">
</div> -->
<div class="contain">
<dv-border-box-7 :color="['#0f2e66', '#139efa']"></dv-border-box-7>
</div>
<div class="login_contain">
<el-form
ref="loginForm"
:model="loginForm"
:rules="loginRules"
class="login-form"
auto-complete="on"
label-position="left"
>
<!-- <div class="title-container">
<h3 class="title">Login Form</h3>
</div> -->
<div class="tit1">
<div class="act">密码登录</div>
<!-- <div>短信登录</div> -->
</div>
<el-form-item prop="username">
<span class="svg-container">
<svg-icon icon-class="user" />
</span>
<el-input
clearable
ref="username"
v-model="loginForm.username"
@blur="getCheck"
placeholder="Username"
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
clearable
:key="passwordType"
ref="password"
v-model="loginForm.password"
:type="passwordType"
placeholder="Password"
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>
<div class="yzm">
<el-form-item prop="code" style="flex: 1">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input
clearable
placeholder="请输入验证码"
v-model.trim="loginForm.code"
@keyup.enter.native="handleLogin"
></el-input>
</el-form-item>
<div class="img">
<img :src="codeUrl" @click="getVerifyCode" />
</div>
</div>
<div class="yzm" v-if="ismsgCode">
<el-form-item prop="smsCode" style="flex: 1">
<span class="svg-container">
<svg-icon icon-class="password" />
</span>
<el-input
clearable
placeholder="请输入短信验证码"
v-model.trim="loginForm.smsCode"
@keyup.enter.native="handleLogin"
></el-input>
</el-form-item>
<div class="img">
<div class="hqyzm1" :class="isSend ? 'hui' : ''" @click="submitForm">{{ getCode }}</div>
</div>
</div>
<el-button
:loading="loading"
type="primary"
class="toLogin"
@click.native.prevent="handleLogin"
>登录</el-button
>
<!-- <div class="tips">
<span style="margin-right:20px;">username: admin</span>
<span> password: any</span>
</div> -->
</el-form>
</div>
</div>
</template>
<script>
import { validUsername } from "@/utils/validate";
import { getCodeImg, userCheck,userSend } from "@/api/user";
export default {
name: "Login",
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error("Please enter the correct user name"));
} else {
callback();
}
};
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error("The password can not be less than 6 digits"));
} else {
callback();
}
};
return {
loginForm: {
// username: 'admin',
// password: 'admin123',
username: "",
password: "",
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入用户名" },
],
password: [
2025-04-01 23:46:26 +08:00
{ required: true, trigger: "blur", message: '请输入密码' },
2025-03-23 09:18:42 +08:00
],
code: [
{ required: true, trigger: "blur", message:"请输入验证码" },
],
smsCode: [
{ required: true, trigger: "blur", message:"请输入短信验证码" },
],
},
loading: false,
passwordType: "password",
redirect: undefined,
codeUrl: "",
ismsgCode:false,
isSend: false,
beginTime: 60,
2025-04-01 23:46:26 +08:00
getCode: '获取验证码',
2025-03-23 09:18:42 +08:00
timer: '',
};
},
watch: {
$route: {
handler: function (route) {
this.redirect = route.query && route.query.redirect;
},
immediate: true,
},
},
created() {
// 获取验证码
this.getVerifyCode();
},
methods: {
startTime() {
if (this.isSend) return
this.isSend = true
this.getCode = this.beginTime + 's后重新发送'
let that = this
this.timer = setInterval(() => {
this.beginTime--
this.getCode = this.beginTime + 's后重新发送'
if (this.beginTime < 0) {
clearInterval(this.timer)
2025-04-01 23:46:26 +08:00
this.getCode = '获取验证码'
2025-03-23 09:18:42 +08:00
this.beginTime = 60
this.isSend = false
}
}, 1000)
},
submitForm(){
if(!this.isSend){
userSend({
userName: this.loginForm.username
}).then(res=>{
this.startTime()
if(res.code == 200){
this.$message({
message: res.msg,
type: "success",
});
}
})
}
},
getCheck() {
userCheck({
userName: this.loginForm.username
}).then(res=>{
if(res.data == 0){
this.ismsgCode = true
}else{
this.ismsgCode = false
}
});
},
getVerifyCode() {
getCodeImg().then((res) => {
this.codeUrl = "data:image/gif;base64," + res.img;
this.loginForm.uuid = res.uuid;
});
},
showPwd() {
if (this.passwordType === "password") {
this.passwordType = "";
} else {
this.passwordType = "password";
}
this.$nextTick(() => {
this.$refs.password.focus();
});
},
handleLogin() {
this.$refs.loginForm.validate((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.getVerifyCode();
this.loginForm.code = "";
this.loading = false;
});
} else {
console.log("error submit!!");
return false;
}
});
},
},
};
</script>
<style lang="scss">
/* 修复input 背景不协调 和光标变色 */
/* Detail see https://github.com/PanJiaChen/vue-element-admin/pull/927 */
$bg: #283443;
$light_gray: #fff;
$cursor: #fff;
@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: #10224c;
$dark_gray: #889aa4;
$light_gray: #eee;
.login-container {
height: 100vh;
// width: 100%;
background-color: $bg;
overflow: hidden;
background: url("~@/assets/images/loginBgd1.gif") no-repeat 0 0;
background-size: 100% 100%;
.login-form {
position: relative;
width: 426px;
max-width: 100%;
// padding: 160px 35px 0;
margin: 0px auto;
margin-top: 25px;
overflow: hidden;
}
.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;
}
}
.yzm {
display: flex;
align-items: center;
justify-content: space-between;
}
.img {
margin-bottom: 18px;
margin-left: 20px;
img {
width: 100px;
height: 50px;
}
}
.top_item {
text-align: center;
height: 100px;
position: relative;
}
.title_no {
font-size: 26px;
margin-top: 10px;
margin-bottom: -30px;
background: -webkit-linear-gradient(
left,
#4278a3,
#fff 25%,
#4278a3 50%,
#fff 75%,
#4278a3
);
color: transparent;
-webkit-background-clip: text;
background-size: 200% 100%;
animation: masked-animation 1.5s infinite linear;
}
@-webkit-keyframes masked-animation {
0% {
background-position: 0 0;
}
100% {
background-position: -100% 0;
}
}
.qiu {
position: absolute;
top: 18%;
img {
width: 600px;
height: 600px;
}
}
.contain {
height: 450px;
width: 600px;
box-sizing: border-box;
display: flex;
flex-direction: column;
position: absolute;
right: 5%;
top: 30%;
// background: url("~@/assets/images/loginBox.gif") no-repeat 0 0;
// background-size: 100% 100%;
// opacity: 0.55;
border-radius: 50px;
}
.login_contain {
height: 450px;
width: 600px;
// height: 640px;
// width: 854px;
position: absolute;
right: 5%;
top: 30%;
}
.toLogin {
background: #0f2e66;
border: 1px solid #5febfb;
box-shadow: 0px 6px 243px 8px rgba(82, 126, 201, 0.17);
border-radius: 5px;
color: #fff;
width: 100%;
border-color: #183467;
padding: 15px;
}
::v-deep .el-form-item__content {
background: #183467;
}
.tit1 {
display: flex;
align-items: center;
color: #fff;
font-size: 24px;
font-weight: 500;
margin-bottom: 10px;
div {
margin-right: 20px;
padding-bottom: 10px;
}
.act {
border-bottom: 2px solid #fff;
}
}
::v-deep .el-form-item {
margin-bottom: 20px !important;
}
::v-deep .el-input__suffix {
line-height: 52px;
}
.hqyzm1 {
width: 100px;
height: 50px;
background: #0f2e66;
border: 1px solid #5febfb;
box-shadow: 0px 6px 243px 8px rgba(82, 126, 201, 0.17);
border-radius: 5px;
color: #fff;
border-color: #183467;
padding: 15px 0px;
color: #fff;
font-size: 10px;
text-align: center;
cursor: pointer;
}
.hui {
opacity: 0.5;
}
</style>