<template> <div class="login"> <!-- 顶部Logo --> <div class="TopLogo"></div> <div class="TopStyle"></div> <div class="TopName">水务产品化体验中心</div> <!-- 登录表单 --> <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form"> <h3 class="title">登录</h3> <el-form-item prop="username"> <el-input v-model="loginForm.username" style="background: #eaf1fb" type="text" size="large" auto-complete="off" placeholder="请输入账号" > <template #prefix> <span class="input-Title">账号</span> </template> </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位大小写字母+数字+特殊符号" @keyup.enter="handleLogin" > <template #prefix> <span class="input-Title">密码</span> </template> </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: 63%" @keyup.enter="handleLogin" > <template #prefix> <span class="input-Title">验证码</span> </template> </el-input> <div class="login-code"> <img :src="codeUrl" @click="getCode" class="login-code-img" /> </div> </el-form-item> <el-checkbox v-model="loginForm.rememberMe" style="margin: 0px 0px 25px 0px"> 记住密码 </el-checkbox> <el-form-item style="width: 100%"> <el-button :loading="loading" size="large" type="primary" style="width: 100%" @click.prevent="handleLogin" class="LoginBurtton" > <span v-if="!loading">登 录</span> <span v-else>登 录 中...</span> </el-button> <div style="float: right" v-if="register"> <router-link class="link-type" :to="'/register'"> 立即注册 </router-link> </div> </el-form-item> </el-form> <!-- 底部 --> <div class="el-login-footer"> <span>Copyright @2023武汉新烽光电股份有限公司</span> </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 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 loading = ref(false); // 验证码开关 const captchaEnabled = ref(true); // 注册开关 const register = ref(false); const redirect = ref(undefined); function handleLogin() { proxy.$refs.loginRef.validate(valid => { if (valid) { loading.value = true; // 勾选了需要记住密码设置在 cookie 中设置记住用户名和密码 if (loginForm.value.rememberMe) { Cookies.set('usernameNF', loginForm.value.username, { expires: 30 }); Cookies.set('passwordNF', encrypt(loginForm.value.password), { expires: 30, }); Cookies.set('TitleIndex',3, { expires: 30 }) Cookies.set('rememberMeNF', loginForm.value.rememberMe, { expires: 30, }); } else { // 否则移除 Cookies.remove('usernameNF'); Cookies.remove('passwordNF'); Cookies.remove('rememberMeNF'); } // 调用action的登录方法 let params = { ...loginForm.value }; params.password = EncryptAES(params.password); userStore .login(params) .then(() => { router.push({ path: redirect.value || '/' }); }) .catch(err => { getCode(); }); } }); } // 获取验证码 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('usernameNF'); const password = Cookies.get('passwordNF'); const rememberMe = Cookies.get('rememberMeNF'); loginForm.value = { username: username === undefined ? loginForm.value.username : username, password: password === undefined ? loginForm.value.password : decrypt(password), rememberMe: rememberMe === undefined ? false : Boolean(rememberMe), }; } getCode(); getCookie(); </script> <style lang="scss" scoped> .login { height: 100%; background-image: url('../assets/images/login-background.jpg'); background-size: cover; position: relative; } .TopLogo { background-image: url('../assets/images/logo.png'); background-size: cover; width: 114px; height: 36px; position: absolute; top: 33px; left: 40px; } .TopStyle { width: 1px; height: 20px; background: #cfd0e5; position: absolute; top: 49px; left: 191px; } .TopName { width: 234px; height: 26px; font-size: 26px; font-family: Source Han Sans CN; font-weight: bold; color: #000046; position: absolute; top: 39px; left: 230px; } .login-form { position: absolute; top: 314px; right: 223px; border-radius: 6px; background: #ffffff; width: 450px; height: 462px; padding: 80px 37px 5px 49px; background-image: url('../assets/images/LoginForm.jpg'); background-size: cover; box-sizing: border-box; .title { text-align: left; margin: 0 0 30px 0px; color: #707070; font-size: 24px; font-family: Source Han Sans CN; font-weight: 600; color: #030a1e; letter-spacing: 3px; } .el-input { height: 40px; input { height: 40px; } } .input-icon { height: 39px; width: 14px; margin-left: 0px; } } .login-tip { font-size: 13px; text-align: center; color: #bfbfbf; } .login-code { width: 33%; height: 40px; float: right; img { cursor: pointer; vertical-align: middle; } } .el-login-footer { position: fixed; bottom: 40px; width: 100%; text-align: center; color: #fff; font-family: Arial; letter-spacing: 1px; height: 18px; font-size: 16px; font-family: Source Han Sans CN; font-weight: bold; color: #5266ab; } .login-code-img { height: 40px; padding-left: 12px; } .LoginBurtton { width: 300px; height: 40px; background: linear-gradient(90deg, #2270ff 0%, #5f98ff 100%); border-radius: 20px; } .input-Title { width: 65px; height: 100%; text-align: left; font-size: 16px; font-family: Source Han Sans CN; font-weight: 500; color: #030a1e; position: relative; &::after { content: ''; width: 1px; height: 14px; background: #d1dff2; position: absolute; right: 0; top: 12px; } } :deep(.el-input__wrapper) { background: #eaf1fb; border: none; } </style>