Files
lc_frontend/src/views/Login/Login.vue
2025-10-17 10:31:13 +08:00

243 lines
7.5 KiB
Vue

<template>
<div :class="prefixCls" class="relative h-[100%]">
<div class="relative mx-auto h-full flex">
<div
v-if="!appStore.getMobile"
:class="`${prefixCls}__left flex-1 bg-#409eff dark:bg-[var(--login-bg-color)] relative p-30px lt-xl:hidden overflow-x-hidden overflow-y-auto`"
>
<!-- 左上角的 logo + 系统标题 -->
<div
class="relative flex items-center text-white mt-30px"
:style="{ marginTop: leftStyle.logo.mt }"
>
<img
alt=""
class="mr-10px"
:style="{ height: leftStyle.logo.height }"
src="@/assets/imgs/logo_white.png"
/>
</div>
<!-- 左边的背景图 + 欢迎语 -->
<Transition
appear
enter-active-class="animate__animated animate__bounceInLeft"
tag="div"
>
<div :style="{ marginTop: leftStyle.bottomText.textMt }">
<div
class="pos-relative w-100% overflow-hidden"
:style="{ height: leftStyle.lottie.boxHeight }"
>
<img
class="pos-absolute"
:style="{
left: 0,
top: 0,
right: 0,
bottom: 0,
width: '100%',
height: '100%',
objectFit: 'contain',
objectPosition: 'center center',
}"
src="@/assets/imgs/singBj2.png"
alt="静态图片描述"
/>
<!-- <vue3-lottie
class="pos-absolute"
:style="{ left: leftStyle.lottie.left, top: leftStyle.lottie.top }"
:animation-data="loginAnimationData"
:height="leftStyle.lottie.height"
:width="leftStyle.lottie.width"
:auto-play="true"
:loop="true"
/> -->
</div>
<div
class="w-100% flex items-center justify-center ml--20px gap-x-5px"
:style="{ marginTop: leftStyle.bottomText.linkMT }"
>
</div>
<div
class="flex justify-center w-100%"
:style="{ marginTop: leftStyle.bottomText.textMt }"
>
<div
class="pos-relative overflow-hidden"
:style="{ width: leftStyle.bottomText.width, height: leftStyle.bottomText.height }"
>
<span class="w-100% flex items-center justify-center ml--20px gap-x-5px" style="color:white;font-size:50px">综合监控系统</span>
</div>
</div>
</div>
</Transition>
</div>
<div
class="relative flex-1 p-30px bg-#e3f0ff lt-sm:p-10px overflow-x-hidden overflow-y-auto"
:class="`${prefixCls}__right`"
>
<!-- 右上角的主题语言选择 -->
<div
class="relative z-2 flex items-center justify-between text-white at-2xl:justify-end at-xl:justify-end"
>
<!-- <div class="flex items-center at-2xl:hidden at-xl:hidden">
<img alt="" class="mr-10px h-32px" src="@/assets/imgs/logo1.png" />
</div> -->
<div class="flex items-center justify-end space-x-10px h-48px">
<ThemeSwitch />
<LocaleDropdown class="dark:text-white lt-xl:text-white" />
</div>
</div>
<!-- 右边的登录界面 -->
<Transition appear enter-active-class="animate__animated animate__bounceInRight">
<div
:class="newClass"
class="pos-relative m-auto z-2 h-[calc(100%-60px)] w-[100%] flex items-center at-2xl:max-w-500px at-lg:max-w-500px at-md:max-w-500px at-xl:max-w-500px"
>
<div class="bg-#fff dark:bg-[var(--login-bg-color)] b-rounded-20px px-20px">
<!-- 账号登录 -->
<LoginForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
<!-- 手机登录 -->
<MobileForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
<!-- 二维码登录 -->
<QrCodeForm class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
<!-- 三方登录 -->
<SSOLoginVue class="m-auto h-auto p-20px lt-xl:(rounded-3xl light:bg-white)" />
</div>
</div>
</Transition>
</div>
<div
class="pos-fixed bottom-0px left-50% lt-md:left-0px lt-sm:left-0px lt-xl:left-0px lt-xl:left-0px z-1"
>
<img class="w-138px block" src="@/assets/imgs/login/login_right_bg_1.png" alt="" />
</div>
<div class="pos-fixed right--38px top--23px">
<img class="w-160px block" src="@/assets/imgs/login/login_right_bg_2.png" alt="" />
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { useDesign } from '@/hooks/web/useDesign'
import { useAppStore } from '@/store/modules/app'
import { ThemeSwitch } from '@/layout/components/ThemeSwitch'
import { LocaleDropdown } from '@/layout/components/LocaleDropdown'
import { useWindowSize } from '@vueuse/core'
import { LoginForm, MobileForm, QrCodeForm, SSOLoginVue } from './components'
import * as loginAnimation from '@/assets/json/login_left.json'
defineOptions({ name: 'Login' })
const { t } = useI18n()
const appStore = useAppStore()
const { getPrefixCls } = useDesign()
const prefixCls = getPrefixCls('login')
const windowSize = useWindowSize()
const loginAnimationData = ref(loginAnimation['default'])
const leftStyle = computed(() => {
const winW = windowSize.width.value
const leftW = winW / 2
const logo = {
height: leftW / 16.5 + 'px',
mt: leftW / 31.9 + 'px'
}
const lottieMagn = leftW / 435
const lottie = {
boxHeight: leftW / 2.39 + 'px',
height: 335 * lottieMagn,
width: 434 * lottieMagn,
left: -(leftW / 38) + 'px',
top: -(leftW / 5.3) + 'px'
}
const bottomText = {
width: leftW / 1.54 + 'px',
height: leftW / 8.68 + 'px',
left: -(leftW / 31.54) + 'px',
linkMT: leftW / 23.87 + 'px',
textMt: leftW / 16.2 + 'px'
}
return { lottie, bottomText, logo }
})
const newClass = computed(() => {
const mobile = appStore.getMobile ? 'is-mobile' : ''
const toggle = appStore.getFullscreen ? 'is-toggle' : ''
return toggle ? toggle : mobile
})
</script>
<style lang="scss" scoped>
$prefix-cls: #{$namespace}-login;
.#{$prefix-cls} {
overflow: auto;
}
.#{$prefix-cls}__left {
background-image: url('@/assets/imgs/singBj1.png');
background-repeat: no-repeat; // 背景图片不重复
background-size: cover; // 背景图片覆盖整个容器
background-position: center center; // 背景图片居中显示
}
.margin-left-50 {
margin-left: 50%;
}
.is-mobile {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(2.5, 1.8);
}
.is-toggle {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.7, 0.6);
}
.is-mobile-bj {
position: absolute;
width: 50vw !important;
height: 100vh;
top: 0;
left: 0;
overflow: hidden;
}
.is-mobile-bj img {
width: 100%;
height: 100%;
object-fit: cover;
position: absolute;
top: 0;
left: 0;
}
.is-mobile-bj .bjOne {
z-index: 1; /* 底层 */
}
.is-mobile-bj .bjTwo {
z-index: 2; /* 上层(值比 bjOne 大即可) */
width: 80%;
height: auto;
float: left;
left: 50%;
top: 50%;
transform: translate(-50%,-45%);
opacity: 0.8;
}
</style>