<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位大小写英文字母+数字+特殊符号 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 => { console.log(res); // 登录成功之后都加载对应路由 permissionStore.generateRoutes(); router.push({ path: '/chengguanweiScreen' }); 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('routerPartKFC'); localStorage.removeItem('routerPartXG'); localStorage.removeItem('fromDoorXG'); getCode(); getCookie(); localStorage.removeItem('routerPartXG'); }); </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>