生产监控前端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
5.8 KiB

2 years ago
<template>
<div :class="['loginContainer', settingsStore.showVideo ? 'videoContainer' : 'picContainer']">
2 years ago
<div class="loginCard">
<el-form ref="loginForm" class="loginForm" :model="loginData" :rules="loginRules">
<div class="title flex items-center">
<span class="flex-1 text-center">{{ $t('login.title') }}</span>
<lang-select />
</div>
<el-form-item prop="username">
<div class="icon">
<i class="iconfont icon-user"></i>
</div>
<el-input class="flex-1" ref="username" name="username" size="large" v-model="loginData.username"
:placeholder="$t('login.username')" />
2 years ago
</el-form-item>
<el-tooltip content="Caps lock is On" placement="right" :disabled="isCapslock === false">
<el-form-item prop="password">
<div class="icon">
<i class="iconfont icon-lock"></i>
</div>
<el-input class="flex-1" name="password" type="password" size="large" v-model="loginData.password"
:placeholder="$t('login.password')" show-password @keyup="checkCapslock" />
2 years ago
</el-form-item>
</el-tooltip>
<!-- <el-form-item prop="verifyCode">
<div class="icon">
<i class="iconfont icon-safe-code"></i>
</div>
<el-input class="flex-1" name="verifyCode" size="large" v-model="loginData.verifyCode"
:placeholder="$t('login.verifyCode')" auto-complete="off" maxlength="6" @keyup.enter="loginClick" />
2 years ago
<div class="captcha">
<img :src="captchaBase64" @click="getCaptcha" />
</div>
</el-form-item> -->
<el-button class="width-100" size="default" type="primary" :loading="loading" @click.prevent="loginClick">
{{ $t('login.login') }}
</el-button>
</el-form>
</div>
<video :style="resizeStyle" autoplay loop muted v-on:canplay="onCanplay" v-if="settingsStore.showVideo">
<source src="../../assets/images/login-bg.mp4" type="video/mp4" />
</video>
<div class="videoCover" v-if="!videoCanPlay && settingsStore.showVideo">
<img :style="resizeStyle" src="../../assets/images/login-bg.png" alt="视频封面">
</div>
<div class="copyright">Copyright © 2023 Daniel {{ $t('login.copyright') }}</div>
2 years ago
</div>
</template>
<script lang="ts" setup>
import router from '@/router';
import LangSelect from '@/components/LangSelect/index.vue';
import { useUserStore } from '@/store/modules/user';
import { LocationQuery, LocationQueryValue, useRoute } from 'vue-router';
import { useSettingsStore } from '@/store/modules/settings';
// import { getCaptchaApi } from '@/api/auth';
2 years ago
import { LoginData } from '@/api/auth/types';
const settingsStore = useSettingsStore();
2 years ago
const userStore = useUserStore();
const route = useRoute();
const loginForm = ref(ElForm);
const isCapslock = ref(false);// 是否大写锁定
const resizeStyle = ref()//视频背景自适应样式
const videoCanPlay = ref(false)
2 years ago
const loginData = ref<LoginData>({
username: '',
password: '',
// verifyCode: ''
2 years ago
});
const loginRules = {
username: [{ required: true, trigger: 'blur', message: '请输入用户名' }],
password: [{ required: true, trigger: 'blur', validator: validatePassword }],
verifyCode: [{ required: true, trigger: 'blur', message: '请输入验证码' }]
};
const loading = ref(false);
const captchaBase64 = ref();
function validatePassword(rule: any, value: any, callback: any) {
if (value.length < 6) {
callback(new Error('密码不能少于6位'));
} else {
callback();
}
}
function checkCapslock(e: any) {
const { key } = e;
isCapslock.value = key && key.length === 1 && key >= 'A' && key <= 'Z';
}
onMounted(() => {
// getCaptcha();
resizeFun()
2 years ago
});
function onCanplay() {
//视频播放事件
videoCanPlay.value = true
2 years ago
}
window.addEventListener('resize', () => {
//监听窗口变化以改变视频背景大小自适应
resizeFun()
})
//获取验证码
// function getCaptcha() {
// getCaptchaApi().then(({ data }) => {
// const { verifyCodeBase64, verifyCodeKey } = data;
// loginData.value.verifyCodeKey = verifyCodeKey;
// captchaBase64.value = verifyCodeBase64;
// });
// }
2 years ago
//登录
function loginClick() {
loginForm.value.validate((valid: boolean) => {
if (valid) {
loading.value = true;
userStore
.login(loginData.value)
.then(() => {
const query: LocationQuery = route.query;
const redirect = (query.redirect as LocationQueryValue) ?? '/';
const otherQueryParams = Object.keys(query).reduce((account: any, current: string) => {
if (current !== 'redirect') {
account[current] = query[current];
}
return account;
}, {});
router.push({ path: redirect, query: otherQueryParams });
})
.finally(() => {
loading.value = false;
// getCaptcha();
});
}
});
}
function resizeFun() {
//视频背景自适应处理
const windowWidth = document.body.clientWidth
const windowHeight = document.body.clientHeight
const windowAspectRatio = windowHeight / windowWidth
let videoWidth
let videoHeight
if (windowAspectRatio < 0.5625) {
videoWidth = windowWidth
videoHeight = videoWidth * 0.5625
resizeStyle.value = {
height: windowWidth * 0.5625 + 'px',
width: windowWidth + 'px',
'margin-bottom': (windowHeight - videoHeight) / 2 + 'px',
'margin-left': 'initial'
}
} else {
videoHeight = windowHeight
videoWidth = videoHeight / 0.5625
resizeStyle.value = {
height: windowHeight + 'px',
width: windowHeight / 0.5625 + 'px',
'margin-left': (windowWidth - videoWidth) / 2 + 'px',
'margin-bottom': 'initial'
}
}
}
2 years ago
</script>
<style lang="scss" scoped>
@import './index.scss';
</style>