Newer
Older
KaiFengPC / src / views / login.vue
@zhangdeliang zhangdeliang on 26 Jun 8 KB update
<template>
  <!-- 登录 -->
  <div class="loginPage">
    <!-- 登录表单 -->
    <div class="formCenter">
      <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="loginForm">
        <div class="flex center">
          <div class="img"></div>
          <el-form-item prop="username">
            <el-input class="userinput" v-model="loginForm.username" type="text" auto-complete="off" placeholder="请输入账号"> </el-input>
          </el-form-item>
        </div>
        <div class="flex center">
          <div class="pass"></div>
          <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>
        </div>
        <el-form-item prop="code" v-if="captchaEnabled" style="display: flex">
          <el-input
            v-model="loginForm.code"
            auto-complete="off"
            placeholder="请输入"
            style="flex: 1"
            @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" @click.prevent="handleLogin" class="loginBtn" :loading="loginLoading">
            <span>登 录</span>
          </el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

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

const userStore = useUserStore();
const router = useRouter();
const { proxy } = getCurrentInstance();
const permissionStore = usePermissionStore();
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位大小写英文字母+数字+特殊符号1
  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('usernameKFC', loginForm.value.username, { expires: 30 });
        Cookies.set('passwordKFC', encrypt(loginForm.value.password), {
          expires: 30,
        });
        Cookies.set('rememberMeKFC', loginForm.value.rememberMe, {
          expires: 30,
        });
      } else {
        // 否则移除
        Cookies.remove('usernameKFC');
        Cookies.remove('passwordKFC');
        Cookies.remove('rememberMeKFC');
      }
      // 调用action的登录方法
      let params = { ...loginForm.value };
      params.password = EncryptAES(params.password);
      userStore
        .login(params)
        .then(res => {
          // 登录成功之后都加载对应路由
          permissionStore.generateRoutes();
          router.push({ path: '/chengguanweiScreen' });
          localStorage.setItem('routerPartXG', 'Project'); //默认加载排水首页
          loginLoading.value = false;
        })
        .catch(err => {
          console.log(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('usernameKFC');
  const password = Cookies.get('passwordKFC');
  const rememberMe = Cookies.get('rememberMeKFC');
  loginForm.value = {
    username: username === undefined ? loginForm.value.username : username,
    password: password === undefined ? loginForm.value.password : decrypt(password),
    rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),
  };
}

onMounted(() => {
  Cookies.remove('xiaogan-Token'); //清除token
  localStorage.removeItem('routerPartKFC');
  localStorage.removeItem('fromDoorKFC');
  localStorage.removeItem('routerPartXG');
  localStorage.removeItem('fromDoorXG');
  getCode();
  getCookie();
});
</script>

<style lang="scss">
.loginPage {
  .formCenter {
    width: 460px;
    padding: 20px;
    // background: #fff;
    background: url('@/assets/images/login/LoginBox.png') no-repeat;
    background-size: 100% 100%;
    border-radius: 8px;
    box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3);
    .logo {
      text-align: center;
      color: #0584ba;
      font-size: 24px;
      font-weight: 400;
      margin: 30px auto;
    }
    .loginForm {
      width: 80%;
      margin-left: 10%;
      margin-top: 15%;
      // .el-form-item:nth-of-type(1) {
      //   background: url('@/assets/images/login/inputUser.png') no-repeat !important;
      //   background-size: 100% 100%;
      // }
      // .el-form-item:nth-of-type(2) {
      //   background: url('@/assets/images/login/inputPass.png') no-repeat !important;
      //   background-size: 100% 100%;
      // }
      .input_box {
        width: 100%;
      }
      .el-form-item {
        margin-bottom: 30px;
        position: relative;
        display: flex;
        flex: 1;

        .el-input {
          width: 100%;
          height: 40px;
          border-color: #8d8d8d !important;

          .el-input__wrapper {
            background: #fff !important;
            box-shadow: none;
            .el-input__inner {
              font-size: 18px;
              color: #8d8d8d !important;
            }
            svg path {
              fill: #0584ba !important;
            }
          }
          .el-input__icon {
            width: 30px;
            height: 30px;
            font-size: 22px;
          }
          input::placeholder {
            font-size: 16px;
          }
        }
        .el-form-item__error {
          left: 5px;
          top: 45px;
          font-size: 15px;
        }

        .loginBtn {
          width: 100%;
          height: 48px;
          font-size: 25px;
          background: url('@/assets/images/login/tab_btn.png') no-repeat;
          background-size: 100% 100%;
          font-family: AlimamaShuHeiTi-Bold;
          font-weight: 300;
          border: none;
        }
      }
      .el-checkbox {
        margin: 0px 0px 15px 5px;
        .el-checkbox__label {
          color: #fff;
        }
      }

      .login-code {
        height: 40px;
        img {
          width: 120px;
          height: 40px;
          cursor: pointer;
        }
      }
      .center {
        .img {
          width: 45px;
          height: 45px;
          background: url('@/assets/images/login/inputUser2.png') no-repeat;
          background-size: 100% 100%;
          position: relative;
          left: 3px;
          top: -2px;
        }
        .pass {
          width: 45px;
          height: 45px;
          background: url('@/assets/images/login/inputPass1.png') no-repeat;
          background-size: 100% 100%;
          position: relative;
          left: 3px;
          top: -2px;
        }
      }
    }
  }
}
</style>