右旗智慧驼厂
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.
 
 
 
 
 
 

437 lines
11 KiB

<template>
<div class="login">
<el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form">
<!-- 品牌区域 -->
<div class="brand-area">
<div class="logo-icon">🐫</div>
<h3 class="title">{{ title }}</h3>
<p class="subtitle">智慧牧场 · 轻松管理</p>
</div>
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
type="text"
auto-complete="off"
placeholder="账号 / 手机号"
class="custom-input"
>
<svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
type="password"
auto-complete="off"
placeholder="密码"
@keyup.enter.native="handleLogin"
class="custom-input"
>
<svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" />
</el-input>
</el-form-item>
<!-- 优化后的验证码区域:更紧凑、对齐美观 -->
<el-form-item prop="code" v-if="captchaEnabled" class="captcha-item">
<div class="captcha-wrapper">
<el-input
v-model="loginForm.code"
auto-complete="off"
placeholder="验证码"
@keyup.enter.native="handleLogin"
class="captcha-input"
>
<svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" />
</el-input>
<div class="captcha-image" @click="getCode">
<img :src="codeUrl" class="captcha-img" alt="验证码" />
<span class="refresh-icon" title="点击刷新">⟳</span>
</div>
</div>
</el-form-item>
<!-- 选项栏:记住密码 + 立即注册 -->
<div class="options-bar">
<el-checkbox v-model="loginForm.rememberMe" class="remember-checkbox">记住密码</el-checkbox>
<router-link v-if="register" class="register-link" to="/register">立即注册</router-link>
</div>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="medium"
type="primary"
class="login-btn"
@click.native.prevent="handleLogin"
>
<span v-if="!loading"> </span>
<span v-else> 中...</span>
</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getCodeImg } from "@/api/login"
import Cookies from "js-cookie"
import { encrypt, decrypt } from '@/utils/jsencrypt'
import defaultSettings from '@/settings'
export default {
name: "Login",
data() {
return {
title: '阿右旗阿拉腾敖包镇骆驼产业标准化智慧化示范基地数据中心',
footerContent: defaultSettings.footerContent,
codeUrl: "",
loginForm: {
username: "admin",
password: "admin123",
rememberMe: false,
code: "",
uuid: ""
},
loginRules: {
username: [
{ required: true, trigger: "blur", message: "请输入您的账号" }
],
password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }
],
code: [{ required: true, trigger: "change", message: "请输入验证码" }]
},
loading: false,
captchaEnabled: true,
register: false,
redirect: undefined,
showDemoTip: true
}
},
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
created() {
this.getCode()
this.getCookie()
},
methods: {
getCode() {
getCodeImg().then(res => {
this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled
if (this.captchaEnabled) {
this.codeUrl = "data:image/gif;base64," + res.img
this.loginForm.uuid = res.uuid
}
})
},
getCookie() {
const username = Cookies.get("username")
const password = Cookies.get("password")
const rememberMe = Cookies.get('rememberMe')
this.loginForm = {
username: username === undefined ? this.loginForm.username : username,
password: password === undefined ? this.loginForm.password : decrypt(password),
rememberMe: rememberMe === undefined ? false : Boolean(rememberMe)
}
},
handleLogin() {
this.$refs.loginForm.validate(valid => {
if (valid) {
this.loading = true
if (this.loginForm.rememberMe) {
Cookies.set("username", this.loginForm.username, { expires: 30 })
Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 })
Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 })
} else {
Cookies.remove("username")
Cookies.remove("password")
Cookies.remove('rememberMe')
}
this.$store.dispatch("Login", this.loginForm).then(() => {
this.$router.push({ path: "/Home" }).catch(() => { });
}).catch(() => {
this.loading = false
if (this.captchaEnabled) {
this.getCode()
}
})
}
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
// 颜色变量 - 驼场主题色(自然、大地、清新)
$primary-color: #7c9a3e; // 草绿色主色调
$primary-hover: #5c7a2e; // 深草绿
$bg-overlay: rgba(0, 0, 0, 0.3);
$text-dark: #2c3a1f;
$text-light: #6b7a5a;
$card-white: rgba(255, 255, 255, 0.96);
$shadow-sm: 0 20px 35px -10px rgba(0, 0, 0, 0.2);
$shadow-focus: 0 0 0 3px rgba(124, 154, 62, 0.2);
.login {
position: relative;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
min-height: 500px;
background: linear-gradient(135deg, #2b5e2b 0%, #8cb36b 50%, #d4c9a3 100%);
overflow: hidden;
// 登录卡片
.login-form {
position: relative;
z-index: 2;
width: 440px;
padding: 40px 35px 35px;
background: $card-white;
backdrop-filter: blur(2px);
border-radius: 32px;
box-shadow: $shadow-sm;
transition: all 0.3s ease;
border: 1px solid rgba(255,255,255,0.5);
&:hover {
transform: translateY(-3px);
box-shadow: 0 25px 40px -12px rgba(0, 0, 0, 0.25);
}
}
// 品牌区
.brand-area {
text-align: center;
margin-bottom: 30px;
.logo-icon {
font-size: 56px;
display: inline-block;
animation: gentleSwing 2s infinite ease;
}
.title {
margin: 12px 0 6px;
font-size: 28px;
font-weight: 600;
color: $text-dark;
letter-spacing: 2px;
}
.subtitle {
font-size: 13px;
color: $text-light;
margin-bottom: 5px;
font-weight: 400;
}
}
// 输入框样式优化
.custom-input {
:deep(.el-input__inner) {
height: 48px;
border-radius: 60px;
border: 1px solid #e2e8e6;
background: #fefef7;
padding-left: 42px;
font-size: 15px;
transition: all 0.2s;
&:focus {
border-color: $primary-color;
box-shadow: $shadow-focus;
}
}
:deep(.el-input__prefix) {
left: 16px;
top: 2px;
.input-icon {
font-size: 18px;
color: $primary-color;
}
}
}
// ========= 优化后的验证码样式 =========
.captcha-item {
margin-bottom: 18px;
:deep(.el-form-item__content) {
line-height: initial;
}
}
.captcha-wrapper {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
}
.captcha-input {
flex: 1;
:deep(.el-input__inner) {
height: 48px;
border-radius: 60px;
border: 1px solid #e2e8e6;
background: #fefef7;
padding-left: 42px;
font-size: 15px;
transition: all 0.2s;
&:focus {
border-color: $primary-color;
box-shadow: $shadow-focus;
}
}
:deep(.el-input__prefix) {
left: 16px;
top: 2px;
.input-icon {
font-size: 18px;
color: $primary-color;
}
}
}
.captcha-image {
position: relative;
flex-shrink: 0;
width: 110px;
height: 48px;
border-radius: 12px;
overflow: hidden;
cursor: pointer;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.2s, box-shadow 0.2s;
&:hover {
transform: scale(1.02);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
.refresh-icon {
opacity: 1;
}
}
}
.captcha-img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.refresh-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 22px;
font-weight: bold;
color: white;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
opacity: 0;
transition: opacity 0.2s;
background: rgba(0, 0, 0, 0.5);
width: 32px;
height: 32px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
backdrop-filter: blur(2px);
pointer-events: none;
}
// 选项栏(记住密码 + 注册)
.options-bar {
display: flex;
justify-content: space-between;
align-items: center;
margin: 8px 0 25px 0;
.remember-checkbox {
:deep(.el-checkbox__inner) {
border-radius: 4px;
border-color: #cbd5e1;
background-color: #fff;
}
:deep(.el-checkbox__input.is-checked .el-checkbox__inner) {
background-color: $primary-color;
border-color: $primary-color;
}
:deep(.el-checkbox__label) {
color: $text-light;
font-size: 13px;
}
}
.register-link {
color: $primary-color;
font-size: 13px;
text-decoration: none;
font-weight: 500;
transition: 0.2s;
&:hover {
color: $primary-hover;
text-decoration: underline;
}
}
}
// 登录按钮
.login-btn {
width: 100%;
height: 48px;
background: $primary-color;
border: none;
border-radius: 60px;
font-size: 16px;
font-weight: 600;
letter-spacing: 2px;
box-shadow: 0 8px 18px rgba(124, 154, 62, 0.3);
transition: all 0.25s;
&:hover, &:focus {
background: $primary-hover;
transform: scale(1.01);
box-shadow: 0 10px 22px rgba(92, 122, 46, 0.4);
}
}
}
// 动画
@keyframes gentleSwing {
0%,100%{ transform: rotate(0deg); }
50%{ transform: rotate(6deg); }
}
// 响应式
@media (max-width: 500px) {
.login .login-form {
width: 88%;
padding: 30px 20px;
}
.captcha-wrapper {
gap: 8px;
}
.captcha-image {
width: 95px;
height: 44px;
}
.captcha-input :deep(.el-input__inner) {
height: 44px;
}
}
</style>