<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>