main-web/src/views/login/login.vue

275 lines
6.9 KiB
Vue
Raw Normal View History

2024-08-20 12:11:33 +00:00
<template>
<div
class="login-container"
:style="{
backgroundImage: `url(${
configs.loginBg || '/web-common-resource/img/bg_login.png'
})`
}"
>
<div class="login-logo">
<img :src="configs.loginLogo" />
</div>
<div class="login-center">
<div class="desc-content">
<span class="desc-title">{{ configs.promotionalTitle }}</span>
<span class="desc-remark">{{ configs.promotionalContent }}</span>
</div>
<el-form
:model="loginForm"
ref="loginFormRef"
label-position="left"
label-width="0px"
class="card-box login-form"
@keyup.enter="handleLogin"
>
<div class="login-title">账号登录</div>
<el-form-item
class="login-form-item"
prop="account"
:rules="[{ ...required, message: '请输入用户名' }]"
>
<el-input
v-model="loginForm.account"
autocomplete="off"
placeholder="登录账户"
>
<template #prefix>
<el-icon>
<icon-ep-user />
</el-icon>
</template>
</el-input>
</el-form-item>
<el-tooltip
:visible="capsTooltip"
content="大写锁定已打开"
placement="right"
:manual="true"
>
<el-form-item
class="login-form-item"
prop="password"
:rules="[{ ...required, message: '请输入密码' }]"
>
<el-input
show-password
v-model="loginForm.password"
placeholder="密码"
@blur="capsTooltip = false"
@keyup="checkCapslock"
>
<template #prefix>
<el-icon><icon-ep-lock /></el-icon>
</template>
</el-input>
</el-form-item>
</el-tooltip>
<el-form-item class="login-form-item">
<div class="operate-region">
<span class="remember">
<el-switch v-model="remember"></el-switch>
<span class="m-l-xs">记住密码</span>
</span>
<a
:href="`mailto:${configs.helpInformationLink}`"
type="text"
class="text-info help-info"
:title="configs.helpInformationContent"
>{{ configs.helpInformationContent }}</a
>
</div>
</el-form-item>
<el-button
class="login-btn"
type="primary"
:loading="loading"
@click="handleLogin"
>登录</el-button
>
</el-form>
</div>
<div class="copyright-info">{{ configs.copyrightInformation }}</div>
</div>
</template>
<script setup lang="ts">
import { decrypt, encrypt } from "utils/crypto";
import { login } from "services";
import { useStore } from "vuex";
import { useRouter, useRoute } from "vue-router";
import setLoginData from "./tools";
import { required } from "@/validate";
import type { FormInstance } from "element-plus";
const loginForm = reactive({
account: "",
password: ""
});
const remember = ref(false);
const loading = ref(false);
const capsTooltip = ref(false);
const store = useStore();
const configs = computed(() => store.getters.pageConfig);
const appConfigs = computed(() => store.getters.appConfigs);
const loginFormRef = ref<FormInstance>();
const init = () => {
const local = localStorage.getItem("cmcLoginData");
if (local) {
const obj = JSON.parse(local);
loginForm.account = obj.account;
loginForm.password = decrypt(obj.password);
remember.value = true;
}
};
init();
const router = useRouter();
const route = useRoute();
function goLogin(data: any) {
setLoginData(data);
if (unref(remember)) {
const obj = {
account: loginForm.account,
password: encrypt(loginForm.password)
};
localStorage.setItem("cmcLoginData", JSON.stringify(obj));
} else {
localStorage.removeItem("cmcLoginData");
}
const { redirect } = route.query;
const path = redirect
? (redirect as string).split("/#")[1]
: appConfigs.value.homePath;
router.replace(path);
localStorage.removeItem("lockData");
}
function handleLogin() {
if(!loginFormRef.value) return;
loginFormRef.value.validate(async (valid) => {
if (valid) {
loading.value = true;
const { account, password } = loginForm;
const res = await login({
account,
password: encrypt(password),
isManager: true
});
if (res.success) {
goLogin(res.data);
}
loading.value = false;
}
});
}
function checkCapslock({ shiftKey, key }: { shiftKey: boolean, key: string}) {
if (key && key.length === 1) {
if (
(shiftKey && key >= "a" && key <= "z") ||
(!shiftKey && key >= "A" && key <= "Z")
) {
capsTooltip.value = true;
} else {
capsTooltip.value = false;
}
}
if (key === "CapsLock" && unref(capsTooltip) === true) {
capsTooltip.value = false;
}
}
</script>
<style lang="scss" scoped>
.login-container {
display: flex;
flex-direction: column;
height: 100vh;
background: url("/web-common-resource/img/bg_login.png") #2d3a4b no-repeat;
background-size: cover;
.login-logo {
padding: 5px 40px;
img {
height: 40px;
}
}
.login-center {
display: flex;
flex: 1;
justify-content: space-around;
align-items: center;
.desc-content {
color: #fff;
display: flex;
flex-direction: column;
margin-top: -150x;
width: 600px;
.desc-title {
font-weight: 700;
font-style: normal;
font-size: 38px;
color: #ffffff;
margin-bottom: 56px;
}
.desc-remark {
line-height: 40px;
font-weight: 400;
font-style: normal;
font-size: 22px;
color: #ffffff;
}
}
.login-form {
box-sizing: border-box;
width: 462px;
padding: 50px 30px;
background: #fff;
font-size: 17px;
.login-title {
font-size: 32px;
text-align: center;
color: #333;
margin-bottom: 50px;
}
.operate-region {
display: flex;
align-items: center;
width: 100%;
.remember {
flex: 1;
text-align: left;
}
}
.login-btn {
margin-top: 20px;
height: 60px;
width: 100%;
}
.help-info {
max-width: 130px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.login-form-item {
:deep(.#{$namespace}-input__wrapper) {
height: 60px;
line-height: 60px;
}
:deep(.#{$namespace}-input__prefix) {
font-size: 20px;
color: #000;
padding: 0 10px;
}
}
}
}
.copyright-info {
padding: 10px 0;
text-align: center;
background: rgba(10, 37, 68, 0.6);
color: #bbbbbb;
}
}
</style>