Files
mayfly-go/frontend/src/views/login/index.vue

334 lines
11 KiB
Vue
Raw Normal View History

<template>
2023-09-23 22:52:05 +08:00
<div class="login-container flex">
<div class="login-left">
<div class="login-left-logo">
<img :src="themeConfig.logoIcon" />
2023-09-23 22:52:05 +08:00
<div class="login-left-logo-text">
<span>{{ themeConfig.globalViceTitle }}</span>
2023-09-23 22:52:05 +08:00
</div>
</div>
<div class="login-left-img">
<img :src="loginBgImg" />
</div>
<img :src="loginBgSplitImg" class="login-left-waves" />
</div>
2024-11-21 19:02:15 +08:00
2023-09-23 22:52:05 +08:00
<div class="login-right flex">
<div class="login-right-warp flex-margin">
2024-11-21 19:02:15 +08:00
<span class="login-right-warp-one"> </span>
2023-09-23 22:52:05 +08:00
<span class="login-right-warp-two"></span>
2024-11-21 19:02:15 +08:00
2023-09-23 22:52:05 +08:00
<div class="login-right-warp-mian">
2024-11-21 19:02:15 +08:00
<div class="login-right-warp-main-title">
{{ themeConfig.globalViceTitle }}
<el-dropdown
:show-timeout="70"
:hide-timeout="50"
trigger="click"
@command="
(lang: string) => {
themeConfig.globalI18n = lang;
}
"
>
<div>
<SvgIcon
:size="16"
:name="EnumValue.getEnumByValue(I18nEnum, themeConfig.globalI18n)?.extra.icon"
:title="$t('layout.user.langSwitch')"
style="margin-top: 50px; margin-left: 20px"
/>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="item in I18nEnum"
:key="item.value"
:command="item.value"
:disabled="themeConfig.globalI18n === item.value"
>
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
2023-09-23 22:52:05 +08:00
<div class="login-right-warp-main-form">
<div v-if="!state.isScan">
<el-tabs v-model="state.tabsActiveName">
2024-11-20 22:43:53 +08:00
<el-tab-pane :label="$t('login.accountPasswordLogin')" name="account">
2023-09-23 22:52:05 +08:00
<Account ref="loginForm" />
</el-tab-pane>
</el-tabs>
</div>
<div class="!mt-4" v-if="state.oauth2LoginConfig.enable">
2024-11-21 19:02:15 +08:00
<el-text size="small">{{ $t('login.thirdPartyLogin') }}: </el-text>
<el-tooltip :content="state.oauth2LoginConfig.name" placement="bottom-start">
2023-09-23 22:52:05 +08:00
<el-button link size="small" type="primary" @click="oauth2Login">
<el-icon :size="18">
<Link />
</el-icon>
</el-button>
</el-tooltip>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
2023-09-23 22:52:05 +08:00
<script setup lang="ts" name="loginIndex">
2023-10-14 16:00:16 +08:00
import { ref, defineAsyncComponent, onMounted, reactive } from 'vue';
2023-03-15 11:41:03 +08:00
import { useThemeConfig } from '@/store/themeConfig';
2023-09-23 22:52:05 +08:00
import loginBgImg from '@/assets/image/login-bg-main.svg';
import loginBgSplitImg from '@/assets/image/login-bg-split.svg';
import openApi from '@/common/openApi';
import config from '@/common/config';
import { storeToRefs } from 'pinia';
2024-11-20 22:43:53 +08:00
import { useI18n } from 'vue-i18n';
2024-11-21 19:02:15 +08:00
import EnumValue from '../../common/Enum';
import { I18nEnum } from '../../common/commonEnum';
2023-09-23 22:52:05 +08:00
// 引入组件
const Account = defineAsyncComponent(() => import('./component/AccountLogin.vue'));
const loginForm = ref<{ loginResDeal: (data: any) => void } | null>(null);
// 定义变量内容
const storesThemeConfig = useThemeConfig();
const { themeConfig } = storeToRefs(storesThemeConfig);
2024-11-20 22:43:53 +08:00
const { locale } = useI18n();
2023-09-23 22:52:05 +08:00
const state = reactive({
tabsActiveName: 'account',
2023-09-23 22:52:05 +08:00
isScan: false,
2023-07-22 20:51:46 +08:00
oauth2LoginConfig: {
2024-11-20 22:43:53 +08:00
name: 'OAuth2 Login',
2023-07-22 20:51:46 +08:00
enable: false,
},
});
onMounted(async () => {
2023-10-14 16:00:16 +08:00
storesThemeConfig.setWatermarkUser(true);
2024-11-20 22:43:53 +08:00
locale.value = themeConfig.value.globalI18n;
2023-07-22 20:51:46 +08:00
state.oauth2LoginConfig = await openApi.oauth2LoginConfig();
});
const oauth2Login = () => {
2023-07-24 22:36:07 +08:00
const width = 700;
const height = 500;
var iTop = (window.screen.height - 30 - height) / 2; //获得窗口的垂直位置;
var iLeft = (window.screen.width - 10 - width) / 2; //获得窗口的水平位置;
// 小窗口打开oauth2鉴权
2023-07-24 22:36:07 +08:00
let oauthWindow = window.open(config.baseApiUrl + '/auth/oauth2/login', 'oauth2', `height=${height},width=${width},top=${iTop},left=${iLeft},location=no`);
if (oauthWindow) {
const handler = (e: any) => {
2023-07-22 20:51:46 +08:00
if (e.data.action === 'oauthLogin') {
window.removeEventListener('message', handler);
loginForm.value!.loginResDeal(e.data);
}
2023-07-22 20:51:46 +08:00
};
window.addEventListener('message', handler);
setInterval(() => {
2023-07-24 22:36:07 +08:00
if (oauthWindow!.closed) {
2023-07-22 20:51:46 +08:00
window.removeEventListener('message', handler);
}
}, 1000);
}
2023-07-22 20:51:46 +08:00
};
</script>
<style scoped lang="scss">
.login-container {
height: 100%;
2023-09-23 22:52:05 +08:00
background: var(--bg-main-color);
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-left {
flex: 1;
position: relative;
background-color: rgba(211, 239, 255, 1);
margin-right: 100px;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-left-logo {
display: flex;
align-items: center;
position: absolute;
top: 50px;
left: 80px;
z-index: 1;
animation: logoAnimation 0.3s ease;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
img {
width: 52px;
height: 52px;
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-left-logo-text {
display: flex;
flex-direction: column;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
span {
margin-left: 10px;
font-size: 28px;
color: #26a59a;
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-left-logo-text-msg {
font-size: 12px;
color: #32a99e;
}
}
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-left-img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 52%;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
img {
width: 100%;
height: 100%;
animation: error-num 0.6s ease;
}
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-left-waves {
position: absolute;
top: 0;
right: -100px;
}
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right {
width: 700px;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right-warp {
border: 1px solid var(--el-color-primary-light-3);
border-radius: 3px;
width: 500px;
position: relative;
overflow: hidden;
background-color: var(--bg-main-color);
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right-warp-one,
.login-right-warp-two {
position: absolute;
display: block;
width: inherit;
height: inherit;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
&::before,
&::after {
content: '';
position: absolute;
z-index: 1;
}
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right-warp-one {
&::before {
filter: hue-rotate(0deg);
top: 0px;
left: 0;
width: 100%;
height: 3px;
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
&::after {
filter: hue-rotate(60deg);
top: -100%;
right: 2px;
width: 3px;
height: 100%;
}
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right-warp-two {
&::before {
filter: hue-rotate(120deg);
bottom: 2px;
right: -100%;
width: 100%;
height: 3px;
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
&::after {
filter: hue-rotate(300deg);
bottom: -100%;
left: 0px;
width: 3px;
height: 100%;
}
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right-warp-mian {
display: flex;
flex-direction: column;
height: 100%;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right-warp-main-title {
2023-10-08 12:14:19 +08:00
height: 110px;
line-height: 110px;
2023-09-23 22:52:05 +08:00
font-size: 27px;
text-align: center;
letter-spacing: 3px;
animation: logoAnimation 0.3s ease;
animation-delay: 0.3s;
color: var(--el-text-color-primary);
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-right-warp-main-form {
flex: 1;
padding: 0 50px 50px;
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
.login-content-main-sacn {
position: absolute;
top: 0;
right: 0;
width: 50px;
height: 50px;
overflow: hidden;
cursor: pointer;
transition: all ease 0.3s;
color: var(--el-color-primary);
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
&-delta {
position: absolute;
width: 35px;
height: 70px;
z-index: 2;
top: 2px;
right: 21px;
background: var(--el-color-white);
transform: rotate(-45deg);
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
&:hover {
opacity: 1;
transition: all ease 0.3s;
color: var(--el-color-primary) !important;
}
2024-11-20 22:43:53 +08:00
2023-09-23 22:52:05 +08:00
i {
width: 47px;
height: 50px;
display: inline-block;
font-size: 48px;
position: absolute;
right: 1px;
top: 0px;
}
}
}
}
}
}
}
</style>