houde_web_back/src/pages/login.vue
2023-04-17 14:38:19 +08:00

312 lines
9.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<route>
{
meta: {
ignoreRouterCheck: true,
ignoreLoginCheck: true
}
}
</route>
<style src="~/styles/login/index.scss"></style>
<template>
<div class="login-container">
<div class="login-background">
<!-- 登录页背景图替换 -->
<!-- <img src="/images/login-background.jpg" alt=""> -->
</div>
<div class="login-big-box">
<div class="login-left-box">
<!-- 登录页左图替换 -->
<img src="/images/login-left.png" alt="">
</div>
<div class="login-middle-line"></div>
<div class="login-right-box">
<form action="" autocomplete="off">
<div class="login-head-box">
<!-- 登录页Logo替换 -->
<img src="/images/logo_login.png" alt="">
<!-- <span>AERWEN</span> -->
</div>
<div class="login-right-title-box">
<!-- 登录页文字替换 -->
登录到 厚德艺术 后台管理平台
<div class="login-right-title-bottom"></div>
</div>
<div class="login-right-form-control-box">
<div class="login-right-form-control-item js-input">
<input type="text" autocomplete="off" name="account" class="login-form-input-control " @focus="formControlAnimation('inputFocus',$event)" @blur="formControlAnimation('inputBlur',$event)" placeholder="请输入账号">
<div class="account-msg msg op0"></div>
<img src="/images/login-user-icon.png" class="login-form-icon" alt="">
</div>
<div class="login-right-form-control-item js-input">
<input type="password" autocomplete="new-password" name="password" class="login-form-input-control " @focus="formControlAnimation('inputFocus',$event)" @blur="formControlAnimation('inputBlur',$event)" placeholder="请输入密码">
<div class="password-msg msg op0"></div>
<img src="/images/login-password-icon.png" class="login-form-icon" alt="">
</div>
<div class="login-right-form-control-item js-input">
<div class="login-right-captcha-box">
<div class="login-right-captcha-input-box">
<input type="text" name="captcha" class=" captcha-input " placeholder="请输入验证码">
<div class="captcha-msg msg op0"></div>
<img src="/images/login-captcha-icon.png" class="login-form-icon" alt="">
</div>
<img :src="`${getCaptcha}?v=${time}`" class="captcha-img" @click="reloadCaptcha" alt="">
</div>
</div>
<div class="login-right-form-control-item js-input">
<a class="login-right-form-control-button js-login-btn" href="#" @click="formSubmit()">
<span class="" >登录</span>
</a>
</div>
</div>
<div class="login-right-copyright-box">
<!-- 登录页版权文字替换 -->
©版权归xxx公司所有
</div>
</form>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import {onMounted, reactive, ref, watch} from 'vue';
import { useRouter } from 'vue-router';
import { useLoginStore } from '~/store';
import { Lock, User } from '@element-plus/icons-vue';
import { getCaptcha } from '~/service/login';
const time = ref();
const login = useLoginStore();
const date = new Date();
const submitForm = formEl => {
// await login.accountLogin(ruleForm);
};
const resetForm = formEl => {
if (!formEl) return;
formEl.resetFields();
};
const reloadCaptcha = () => {
time.value = new Date().getTime();
};
reloadCaptcha();
window.onkeydown=function(e){
if(e.code === 'Enter'){
formSubmit()
}
}
/**按钮提交事件*/
async function formSubmit(){
let oBtn = document.getElementsByClassName('js-login-btn')[0]
let oBtnSpan = oBtn.getElementsByTagName('span')[0]
let verifyPass = false
for (let rKey in regPool) {
verifyPass = verify(msg?.[rKey]?.value || '',rKey,regPool,msg).pass
}
if(verifyPass){
oBtnSpan.innerText='登录中...'
oBtn.style.setProperty("pointer-events", "none")
login.accountLogin({
account:msg['account'].value,
password:msg['password'].value,
captcha:msg['captcha'].value
}).catch(res=>{
oBtnSpan.innerText='登录'
oBtn.style.setProperty("pointer-events", "auto")
})
}else{
}
}
/**消息容器*/
const msg = reactive({})
/**验证器*/
const regPool = {
account:{
r:/^(?![\s!@#])[^!@#]*(?![\s!@#]).$/,
m:'用户名不能有空和空格'
},
password:{
r:/^(?![\s!@#])[^!@#]*(?![\s!@#]).$/,
m:'密码不能有空和空格'
},
captcha:{
done: function (ctx,item){
if(!/^(?![\s!@#])[^!@#]*(?![\s!@#]).$/.test(item.value)){
return '验证码不能有空和空格'
}else{
return true
}
}
}
}
/**输入框输入事件公用逻辑,内置函数防抖*/
function inputEvent(){
let timer
return function (name) {
if (timer!==null){
clearTimeout(timer)
}
timer = setTimeout(() => {
verify(this.value, name, regPool, msg)
}, 500)
}
}
/**监听验证器*/
watch(msg,(n,o)=>{
for (const key in n) {
dispatchMsg(n[key].msg,key+'-msg',function (tag,txt){
txt !=='' ? tag.classList.remove('op0') : tag.classList.add('op0')
})
}
},{deep:true})
/**绑定输入框输入事件*/
onMounted(()=>{
[].map.call(document.querySelectorAll('.js-input input'),function (item,idx){
item.addEventListener('input',inputEvent().bind(item,item.getAttribute('name'),false))
})
})
/**
*
* @param type
* @param e
* @author hyw
* 表单控件的动画效果
*/
const formControlAnimation = (type,e)=>{
let oInput = e.target,
oImg = document.getElementsByClassName('login-form-icon')[[...document.getElementsByClassName('login-form-input-control')].indexOf(e.target)]
new Promise((s,j)=>{
const animationType = {
'inputFocus':()=>{
oImg.classList.add('t5s')
s('inputFocus')
},
'inputBlur':()=>{
oImg.classList.remove('t5s')
s('inputBlur')
}
}
animationType[type]()
}).then(cn=>{
cn==='inputFocus' ? oInput.classList.add('inputFocus') : oInput.classList.remove('inputFocus')
})
}
/**
*
* @param txt 消息文本
* @param tag *要派发的容器可以是样式名也可以是dom节点
* @param cb 回调 参数1为派发的容器参数2为文本
* @author hyw
* @description 将消息派发到dom上配合验证器一起食用将txt派发到tag容器里,只能用于事件处理函数中
*/
function dispatchMsg(txt, tag, cb=undefined) {
txt = txt===true ? '' : txt
let dom =
typeof tag === 'string' ? document.getElementsByClassName(tag)[0] : tag;
dom !== undefined &&
(() => {
if (txt !== dom.innerText) {
dom.innerText = txt;
}
})();
cb && cb(tag !== 'string' ? document.getElementsByClassName(tag)[0] : tag,txt)
}
/**
*
* @param v 对应的输入框值
* @param t 对应的name
* @param regPool 规则集要与输入框name对应上
* @param msg 结果容器,通过验证则对应的msg为true否则则为false
* @description 验证器v4.0
* @module if-else策略优化模式
* @author hyw
* @return verifyObj
* @regPoolDescription 规则集文档:
* r规则一般传入正则当传入一个对象时里面必须包含test方法其内容将作为参数传入
* m消息当不符合规则则消息派发
* c是否为可选默认false
* done回调函数msg上下文将作为第一个参数注册item将作为第二个参数传入返回值将作为msg且r跟m将失效done可以为async
* @regPoolExample 实例:
* {
* curriculum_activity_name: {
* r: /^\S+$/,
* m: '活动名称不能为空捏或首尾不能有空格!'
* },
* curriculum_activity_price: {
* r: /^\+?((0|([0-9]+\d*))|((0\.\d+)|([1-9]+\d*\.\d+)))$/,
* m: '价格不能为负数',
* c: true
* },
* }
*/
function verify(v, t, regPool, msg) {
regPool[t] !== undefined
? (async () => {
msg[t] = {};
msg[t].value = v;
let is = regPool[t]?.r ? regPool[t].r.test(v) : true;
if (is) {
msg[t].msg = true;
} else {
msg[t].msg = true;
msg[t].msg = regPool[t].m;
if (regPool[t]?.c) {
//nice try 包装类
msg[t].value === '' ? (msg[t].msg = true) : regPool[t].m;
msg[t].msg = new String(msg[t].msg);
msg[t].msg.type = '可选';
}
}
if (regPool[t]?.done && regPool[t]?.c) {
msg[t].msg = regPool[t]?.done instanceof Promise ? new String(await regPool[t]?.done(msg, msg[t])) : new String(regPool[t]?.done(msg, msg[t]));
msg[t].msg.type = '可选';
} else if (regPool[t]?.done && !regPool[t]?.c) {
msg[t].msg = regPool[t]?.done instanceof Promise ? regPool[t]?.done(msg, msg[t]) : regPool[t]?.done(msg, msg[t]);
}
msg[t].msg===undefined && (msg[t].msg = false)
})()
: (msg[t].msg = true)
let inputNum = 0,
inputPassNum = 0
for (let key in regPool) {
inputNum +=1
if((key in msg) && msg[key].msg === true){
inputPassNum +=1
}
}
// console.log(inputNum,inputPassNum)
return {
pass:inputNum === inputPassNum
}
}
</script>
<style>
.login-background{
background-image: linear-gradient(to top, #A30000,60%,rgba(145, 2, 2, 0.5) 160%);
}
.login-right-title-bottom{
background-color: #A30000 !important;
}
</style>