Files
----/前端源码/uni-app/pages/login/login.vue

186 lines
4.4 KiB
Vue

<template>
<view
class="login-page login-page--fantasy"
:class="{ 'login-page--desktop': isDesktop, 'login-page--mobile': !isDesktop }"
>
<MysticFantasyBg />
<!-- 登录页面 -->
<LoginScreen v-if="showLogin" @success="handleLoginSuccess" />
</view>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import LoginScreen from '../../components/screens/Login.vue';
import MysticFantasyBg from '../../components/MysticFantasyBg.vue';
import type { MobileLoginResponse, MobileRegisterResponse, ForgotPasswordResponse } from '../../api/types';
import { setToken, setUserInfo, isLoggedIn } from '../../utils/auth';
import { getIsDesktopLayout } from '../../utils/device-layout';
const router = useRouter();
const route = useRoute();
const redirectUrl = ref('/');
const showLogin = ref(false);
const isDesktop = ref(
typeof window !== 'undefined' ? getIsDesktopLayout() : false,
);
const syncDeviceLayout = () => {
if (typeof window === 'undefined') return;
isDesktop.value = getIsDesktopLayout();
};
onUnmounted(() => {
if (typeof window !== 'undefined') {
window.removeEventListener('resize', syncDeviceLayout);
}
});
// 获取页面参数
try {
if (route.query.redirect) {
redirectUrl.value = decodeURIComponent(route.query.redirect as string);
}
} catch (e) {
console.error('获取页面参数失败:', e);
}
const navigateToTarget = () => {
const targetUrl = redirectUrl.value || '/';
router.replace(targetUrl);
};
onMounted(() => {
syncDeviceLayout();
if (typeof window !== 'undefined') {
window.addEventListener('resize', syncDeviceLayout, { passive: true });
}
if (isLoggedIn()) {
if (typeof window !== 'undefined' && getIsDesktopLayout()) {
router.replace('/test-name-live');
} else {
navigateToTarget();
}
} else {
showLogin.value = true;
}
});
const handleLoginSuccess = (data: MobileLoginResponse | MobileRegisterResponse | ForgotPasswordResponse) => {
if (data.access_token) {
setToken(data.access_token);
}
if (data.user_info) {
setUserInfo(data.user_info);
}
setTimeout(() => {
if (typeof window !== 'undefined' && getIsDesktopLayout()) {
router.replace('/test-name-live');
return;
}
navigateToTarget();
}, 300);
};
</script>
<style scoped>
.login-page {
width: 100%;
min-height: 100vh;
position: relative;
overflow: hidden;
}
/* 盖住 Login 组件自带米色宣纸底(含 rice-paper 纹理),避免与玄幻底冲突 */
.login-page--fantasy :deep(.login-screen) {
background: transparent !important;
position: relative;
z-index: 2;
}
.login-page--fantasy :deep(.login-bg),
.login-page--fantasy :deep(.login-bg-pattern) {
opacity: 0 !important;
visibility: hidden !important;
}
/* 电脑端:表单区深色玄幻风 */
.login-page--desktop :deep(.login-screen) {
min-height: 100vh;
position: relative;
z-index: 2;
}
.login-page--desktop :deep(.login-bg) {
opacity: 0;
}
.login-page--desktop :deep(.login-content) {
max-width: 440px;
}
.login-page--desktop :deep(.login-title) {
color: #f2e6d8;
text-shadow: 0 0 24px rgba(212, 175, 55, 0.25);
}
.login-page--desktop :deep(.login-subtitle) {
color: rgba(233, 233, 239, 0.72);
}
.login-page--desktop :deep(.login-form-wrapper) {
background: rgba(15, 23, 42, 0.55);
border: 1px solid rgba(212, 175, 55, 0.22);
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45);
backdrop-filter: blur(12px);
}
.login-page--desktop :deep(.login-tabs) {
border-bottom-color: rgba(212, 175, 55, 0.2);
}
.login-page--desktop :deep(.login-tab.active) {
color: #d4af37;
}
.login-page--desktop :deep(.login-tab.active::after) {
background: linear-gradient(90deg, rgba(212, 175, 55, 0.2), #d4af37, rgba(212, 175, 55, 0.2));
}
.login-page--desktop :deep(.login-tab-text) {
color: rgba(233, 233, 239, 0.78);
}
.login-page--desktop :deep(.login-tab.active .login-tab-text) {
color: #d4af37;
}
.login-page--desktop :deep(.login-form-label) {
color: rgba(242, 230, 216, 0.92);
}
.login-page--desktop :deep(.login-form-input) {
background: rgba(2, 6, 23, 0.45);
border-color: rgba(148, 163, 184, 0.35);
color: #f2e6d8;
}
.login-page--desktop :deep(.login-agreement-text) {
color: rgba(233, 233, 239, 0.55);
}
.login-page--desktop :deep(.login-agreement-link) {
color: #d4af37;
}
.login-page--desktop :deep(.login-forgot-text),
.login-page--desktop :deep(.login-back-text) {
color: #d4af37;
}
</style>