Newer
Older
KaiFengPC / src / views / login.vue
@zhangdeliang zhangdeliang on 20 May 7 KB 项目初始化
<template>
  <!-- 登录 -->
  <div class="loginPage">
    <div class="loginBox">
      <!-- 登录表单 -->
      <div class="formCenter">
        <img src="@/assets/images/login/logo.png" alt="logo" class="logo" />
        <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="loginForm">
          <img src="@/assets/images/login/title.png" alt="logo" class="title" />
          <el-form-item prop="username">
            <el-input v-model="loginForm.username" type="text" size="large" auto-complete="off" placeholder="请输入账号"> </el-input>
          </el-form-item>
          <el-form-item prop="password">
            <el-input
              v-model="loginForm.password"
              type="password"
              size="large"
              auto-complete="off"
              placeholder="8-20位大小写字母+数字+特殊符号"
              show-password
              @keyup.enter="handleLogin"
            >
            </el-input>
          </el-form-item>
          <el-form-item prop="code" v-if="captchaEnabled">
            <el-input
              v-model="loginForm.code"
              size="large"
              auto-complete="off"
              placeholder="请输入"
              style="width: 47%"
              @keyup.enter="handleLogin"
              maxlength="8"
            >
            </el-input>
            <div class="login-code">
              <img :src="codeUrl" @click="getCode" />
            </div>
          </el-form-item>
          <el-checkbox v-model="loginForm.rememberMe" size="large"> 记住密码 </el-checkbox>
          <el-form-item>
            <el-button size="large" type="primary" @click.prevent="handleLogin" class="loginBtn" :loading="loginLoading">
              <span>登 录</span>
            </el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
  </div>
</template>

<script setup>
import { getCodeImg } from '@/api/login';
import Cookies from 'js-cookie';
import { encrypt, decrypt } from '@/utils/jsencrypt';
import { EncryptAES } from '@/utils/AES.js';
import useUserStore from '@/store/modules/user';

const userStore = useUserStore();
const router = useRouter();
const { proxy } = getCurrentInstance();

const loginLoading = ref(false);
const loginForm = ref({
  username: '',
  password: '',
  rememberMe: false,
  code: '',
  uuid: '',
});
const loginRules = {
  username: [{ required: true, trigger: 'blur', message: '请输入您的账号' }],
  code: [{ required: true, trigger: 'blur', message: '请输入验证码' }],
  password: [
    {
      min: 8,
      max: 20,
      message: '8-20位大小写字母+数字+特殊符号',
      required: true,
      trigger: 'blur',
      validator: validPassword,
    },
  ],
};
function validPassword(rule, value, callback) {
  // 密码校验 至少8位大小写英文字母+数字+特殊符号
  let reg = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[^\w\s]).{8,20}$/;
  if (!reg.test(value)) {
    callback(new Error('密码8-20位大小写英文字母+数字+特殊符号'));
  } else {
    callback();
  }
}

const codeUrl = ref('');
// 验证码开关
const captchaEnabled = ref(true);

function handleLogin() {
  proxy.$refs.loginRef.validate(valid => {
    if (valid) {
      loginLoading.value = true;
      // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码
      if (loginForm.value.rememberMe) {
        Cookies.set('usernameKF', loginForm.value.username, { expires: 30 });
        Cookies.set('passwordKF', encrypt(loginForm.value.password), {
          expires: 30,
        });
        Cookies.set('rememberMeKF', loginForm.value.rememberMe, {
          expires: 30,
        });
      } else {
        // 否则移除
        Cookies.remove('usernameKF');
        Cookies.remove('passwordKF');
        Cookies.remove('rememberMeKF');
      }
      // 调用action的登录方法
      let params = { ...loginForm.value };
      params.password = EncryptAES(params.password);
      userStore
        .login(params)
        .then(() => {
          router.push({ path: '/index' });
          loginLoading.value = false;
        })
        .catch(err => {
          getCode();
          loginLoading.value = false;
        });
    }
  });
}
// 获取验证码
function getCode() {
  getCodeImg().then(res => {
    captchaEnabled.value = res.captchaEnabled === undefined ? true : res.captchaEnabled;
    if (captchaEnabled.value) {
      codeUrl.value = 'data:image/gif;base64,' + res.img;
      loginForm.value.uuid = res.uuid;
    }
  });
}

function getCookie() {
  const username = Cookies.get('usernameKF');
  const password = Cookies.get('passwordKF');
  const rememberMe = Cookies.get('rememberMeKF');
  loginForm.value = {
    username: username === undefined ? loginForm.value.username : username,
    password: password === undefined ? loginForm.value.password : decrypt(password),
    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
  };
}

onMounted(() => {
  getCode();
  getCookie();
  localStorage.removeItem('routerPartXG');
});
</script>

<style lang="scss">
.loginPage {
  width: 100%;
  height: 100%;
  background: url('@/assets/images/login/loginBg.png') no-repeat;
  background-size: 100% 100%;
  position: relative;

  .loginBox {
    width: 600px;
    height: 100%;
    position: absolute;
    right: 80px;
    top: 0px;
    display: flex;
    align-items: center;
    justify-content: center;
    .formCenter {
      width: 500px;
      height: 683px;
      position: relative;
      overflow: hidden;
      .logo {
        width: 100%;
      }
      .title {
        width: 400px;
        height: 100px;
      }
      .loginForm {
        margin-left: 60px;
        .el-form-item:nth-of-type(1),
        .el-form-item:nth-of-type(3) {
          background: url('@/assets/images/login/inputUser.png') no-repeat;
          background-size: 100% 100%;
        }
        .el-form-item:nth-of-type(2) {
          background: url('@/assets/images/login/inputPass.png') no-repeat;
          background-size: 100% 100%;
        }
        .el-form-item {
          width: 401px;
          height: 80px;

          .el-input {
            width: calc(100% - 92px);
            height: 50px;
            margin: 0px 0px 0px 70px;

            .el-input__wrapper {
              background: transparent;
              box-shadow: none;
              .el-input__inner {
                font-size: 22px;
              }
            }
            input::placeholder {
              font-size: 16px;
            }
          }
          .el-form-item__error {
            left: 20px;
            top: 75px;
            font-size: 15px;
          }
          .loginBtn {
            width: 456px;
            height: 48px;
            background: url('@/assets/images/login/loginBtn.png') no-repeat;
            background-size: 100% 100%;
            font-size: 28px;
            font-family: PangMenZhengDao;
            font-weight: 400;
            margin-left: 23px;
            border: none;
          }
        }
        .el-checkbox {
          margin: 0px 0px 25px 20px;
          .el-checkbox__label {
            color: #fff;
          }
        }

        .login-code {
          float: right;
          img {
            width: 120px;
            height: 45px;
            margin-top: 10px;
          }
        }
      }
    }
  }
}
</style>