2025-07-25 19:31:28 +08:00

214 lines
4.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>