214 lines
4.6 KiB
Vue
214 lines
4.6 KiB
Vue
<template>
|
||
<div class="login-container">
|
||
<div class="bg-container">
|
||
<img :src="bgImg" alt="登录背景" />
|
||
</div>
|
||
<div class="bottom-text">
|
||
<p>© Byz解忧杂货铺</p>
|
||
</div>
|
||
<div class="content-container">
|
||
<button class="back-btn" @click="handleBack" title="返回主界面">
|
||
返回主界面
|
||
</button>
|
||
<div class="form-content">
|
||
<LoginModule
|
||
ref="loginModuleRef"
|
||
v-if="!showRegister && !showForget"
|
||
@register="showRegister = true"
|
||
@forget="handleSwitchToForget"
|
||
/>
|
||
<RegisterModule
|
||
v-else-if="showRegister"
|
||
@login="handleSwitchToLogin"
|
||
/>
|
||
<ForgetModule
|
||
v-else-if="showForget"
|
||
@login="handleSwitchToLogin"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted } from 'vue'
|
||
import { useRouter } from 'vue-router'
|
||
import { hasValidToken } from '@/utils/jwt'
|
||
import loginBg from '@/assets/login_1.jpg'
|
||
import loginBg1 from '@/assets/login_2.jpg'
|
||
import loginBg3 from '@/assets/login_3.jpg'
|
||
import loginBg4 from '@/assets/login_4.jpg'
|
||
import loginBg5 from '@/assets/login_5.jpg'
|
||
import ForgetModule from "@/components/forget_module.vue";
|
||
import LoginModule from '@/components/login_module.vue'
|
||
import RegisterModule from '@/components/register_module.vue'
|
||
|
||
const images = [loginBg, loginBg1,loginBg3, loginBg4,loginBg5]
|
||
const randomIndex = Math.floor(Math.random() * images.length)
|
||
const bgImg = ref(images[randomIndex])
|
||
|
||
const router = useRouter()
|
||
const showRegister = ref(false)
|
||
const showForget = ref(false)
|
||
const loginModuleRef = ref(null)
|
||
|
||
const handleBack = () => {
|
||
router.push('/')
|
||
}
|
||
|
||
// 处理从注册模块切换到登录模块
|
||
const handleSwitchToLogin = () => {
|
||
showRegister.value = false
|
||
showForget.value = false
|
||
// 在下一个tick中重置登录表单,确保组件已经渲染
|
||
setTimeout(() => {
|
||
if (loginModuleRef.value) {
|
||
loginModuleRef.value.resetForm()
|
||
}
|
||
}, 0)
|
||
}
|
||
|
||
// 处理切换到忘记密码页面
|
||
const handleSwitchToForget = () => {
|
||
showForget.value = true
|
||
showRegister.value = false
|
||
}
|
||
|
||
// 检查登录状态,如果已登录则跳转到首页
|
||
onMounted(() => {
|
||
if (hasValidToken()) {
|
||
router.replace('/')
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.login-container {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
position: relative;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.bg-container {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
z-index: 1;
|
||
}
|
||
|
||
.bg-container img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
object-position: left;
|
||
}
|
||
|
||
.content-container {
|
||
position: relative;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 400px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
z-index: 2;
|
||
padding: 2rem;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border-radius: 16px;
|
||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
||
backdrop-filter: blur(5px);
|
||
-webkit-backdrop-filter: blur(5px);
|
||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
}
|
||
|
||
.back-btn {
|
||
position: absolute;
|
||
top: 18px;
|
||
left: 18px;
|
||
background: #e6f7ff;
|
||
color: #409eff;
|
||
border: none;
|
||
border-radius: 18px;
|
||
padding: 6px 18px 6px 14px;
|
||
font-size: 15px;
|
||
font-weight: 500;
|
||
box-shadow: 0 2px 8px rgba(64,158,255,0.10);
|
||
cursor: pointer;
|
||
transition: background 0.2s, color 0.2s;
|
||
z-index: 10;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
.back-btn:hover {
|
||
background: #b3e5fc;
|
||
color: #1976d2;
|
||
}
|
||
|
||
.form-content {
|
||
width: 100%;
|
||
margin-top: 48px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
}
|
||
|
||
@media (max-width: 600px) {
|
||
.content-container {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
min-width: 0;
|
||
left: 0;
|
||
top: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
transform: none;
|
||
border-radius: 0;
|
||
background: rgba(0,0,0,0.18);
|
||
backdrop-filter: blur(16px);
|
||
-webkit-backdrop-filter: blur(16px);
|
||
padding: 0 8px;
|
||
justify-content: flex-start;
|
||
}
|
||
.back-btn {
|
||
top: 18px;
|
||
left: 18px;
|
||
border-radius: 16px;
|
||
font-size: 15px;
|
||
padding: 6px 14px;
|
||
}
|
||
.form-content {
|
||
margin-top: 64px;
|
||
width: 100%;
|
||
align-items: center;
|
||
}
|
||
}
|
||
|
||
.bottom-text {
|
||
position: absolute;
|
||
left: 24px;
|
||
bottom: 24px;
|
||
z-index: 2;
|
||
color: #fff;
|
||
font-size: 16px;
|
||
font-weight: 300;
|
||
letter-spacing: 1px;
|
||
text-shadow: 0 2px 8px rgba(0,0,0,0.25);
|
||
background: rgba(0, 0, 0, 0.18);
|
||
border-radius: 8px;
|
||
padding: 6px 18px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.10);
|
||
user-select: none;
|
||
transition: background 0.3s;
|
||
}
|
||
|
||
.bottom-text p {
|
||
margin: 0;
|
||
opacity: 0.92;
|
||
}
|
||
</style> |