1167 lines
22 KiB
Vue
1167 lines
22 KiB
Vue
<template>
|
|
<div class="login-page">
|
|
<!-- 全屏背景 -->
|
|
<div class="login-background"></div>
|
|
|
|
<!-- 右上角控制组件 -->
|
|
<div class="top-right-controls">
|
|
<div class="controls-container">
|
|
<ThemeToggle
|
|
position="top-right"
|
|
:tooltip-text="t('login.theme_toggle_tooltip')"
|
|
/>
|
|
<LanguageToggle
|
|
position="top-right"
|
|
:tooltip-text="t('login.language_toggle_tooltip')"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<!-- 主登录卡片 -->
|
|
<div class="login-container">
|
|
<div class="login-card">
|
|
<!-- Google 登录按钮 -->
|
|
<div class="google-login-section">
|
|
<GoogleOAuthButton
|
|
@success="handleLoginSuccess"
|
|
:disabled="false"
|
|
:code="inviteCode"
|
|
/>
|
|
</div>
|
|
<!-- 分割线 -->
|
|
<div class="divider">
|
|
<div class="divider-line"></div>
|
|
<span class="divider-text">{{ t('login.divider_text') }}</span>
|
|
<div class="divider-line"></div>
|
|
</div>
|
|
<!-- 邮箱登录表单 -->
|
|
<div class="email-login-section">
|
|
<LoginForm
|
|
@login="handleLogin"
|
|
@update:inviteCode="updateInviteCode"
|
|
/>
|
|
</div>
|
|
<!-- 错误提示 -->
|
|
<div v-if="authStore.error" class="error-message">
|
|
<el-icon class="error-icon"><WarningFilled /></el-icon>
|
|
<span>{{ authStore.error }}</span>
|
|
</div>
|
|
<!-- 忘记密码和注册链接 -->
|
|
<div class="auth-links">
|
|
<div class="auth-links-row">
|
|
<button
|
|
type="button"
|
|
class="auth-link forgot-password-link"
|
|
@click="goToForgotPassword"
|
|
>
|
|
<el-icon class="link-icon"><QuestionFilled /></el-icon>
|
|
<span>{{ t('login.forgot_password') }}</span>
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
class="auth-link register-link"
|
|
@click="goToRegister"
|
|
>
|
|
<el-icon class="link-icon"><UserFilled /></el-icon>
|
|
<span>{{ t('login.register_account') }}</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { onMounted, reactive, ref, computed } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useAuthStore } from '@/stores/auth'
|
|
import { WarningFilled, InfoFilled, QuestionFilled, UserFilled } from '@element-plus/icons-vue'
|
|
// 导入子组件
|
|
import GoogleOAuthButton from '@/components/auth/GoogleOAuthButton.vue'
|
|
import LoginForm from '@/components/auth/LoginForm.vue'
|
|
import ThemeToggle from '@/components/ui/ThemeToggle.vue'
|
|
import LanguageToggle from '@/components/ui/LanguageToggle.vue'
|
|
import LOGIN from './login'
|
|
const router = useRouter()
|
|
const authStore = useAuthStore()
|
|
const { t } = useI18n()
|
|
const plugin = reactive(new LOGIN());
|
|
|
|
// 邀请码状态管理
|
|
const inviteCode = ref('')
|
|
const isInviteCodeValid = computed(() => {
|
|
return inviteCode.value.trim() !== ''
|
|
})
|
|
|
|
// 更新邀请码
|
|
const updateInviteCode = (value) => {
|
|
inviteCode.value = value
|
|
}
|
|
|
|
const handleLogin = async (data) => {
|
|
plugin.login(data)
|
|
// if (data.inviteCode) {
|
|
// plugin.login(data)
|
|
// } else {
|
|
// plugin.joinWaitlist(data)
|
|
// }
|
|
}
|
|
// 处理登录成功
|
|
const handleLoginSuccess = (userData) => {
|
|
plugin.handleLoginSuccess(userData)
|
|
// console.log('登录成功:', userData)
|
|
// 跳转到默认页面或用户角色对应页面
|
|
// router.push('/czhome')
|
|
}
|
|
|
|
// 跳转到忘记密码页面
|
|
const goToForgotPassword = () => {
|
|
router.push('/forgot-password')
|
|
}
|
|
// 跳转到注册页面
|
|
const goToRegister = () => {
|
|
router.push('/register')
|
|
}
|
|
|
|
// 页面挂载时初始化认证状态
|
|
onMounted(() => {
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* 登录页面基础样式 */
|
|
.login-page {
|
|
position: relative;
|
|
min-height: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* 全屏背景渐变 */
|
|
.login-background {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(135deg,
|
|
#6B46C1 0%,
|
|
#8B5CF6 25%,
|
|
#A78BFA 50%,
|
|
#DDD6FE 75%,
|
|
#F3F4F6 100%);
|
|
background-size: 400% 400%;
|
|
animation: gradientShift 8s ease infinite;
|
|
}
|
|
|
|
@keyframes gradientShift {
|
|
0% { background-position: 0% 50%; }
|
|
50% { background-position: 100% 50%; }
|
|
100% { background-position: 0% 50%; }
|
|
}
|
|
|
|
/* 主登录容器 */
|
|
.login-container {
|
|
position: relative;
|
|
z-index: 10;
|
|
width: 100%;
|
|
max-width: 440px;
|
|
padding: 20px;
|
|
}
|
|
|
|
/* 登录卡片 */
|
|
.login-card {
|
|
background: rgba(255, 255, 255, 0.95);
|
|
backdrop-filter: blur(20px);
|
|
border-radius: 24px;
|
|
padding: 48px 40px;
|
|
box-shadow:
|
|
0 20px 25px -5px rgba(0, 0, 0, 0.1),
|
|
0 10px 10px -5px rgba(0, 0, 0, 0.04),
|
|
0 0 0 1px rgba(139, 92, 246, 0.1);
|
|
border: 1px solid rgba(139, 92, 246, 0.2);
|
|
transform: translateY(0);
|
|
transition: all 0.3s ease;
|
|
animation: slideInUp 0.6s ease-out;
|
|
position: relative;
|
|
overflow: hidden;
|
|
}
|
|
|
|
/* 卡片微妙的背景动画 */
|
|
.login-card::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: linear-gradient(135deg,
|
|
rgba(139, 92, 246, 0.03) 0%,
|
|
transparent 50%,
|
|
rgba(167, 139, 250, 0.03) 100%);
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
}
|
|
|
|
@keyframes slideInUp {
|
|
from {
|
|
opacity: 0;
|
|
transform: translateY(30px);
|
|
}
|
|
to {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
}
|
|
|
|
.login-card:hover {
|
|
transform: translateY(-2px);
|
|
box-shadow:
|
|
0 25px 30px -5px rgba(0, 0, 0, 0.15),
|
|
0 15px 15px -5px rgba(0, 0, 0, 0.1),
|
|
0 0 0 1px rgba(139, 92, 246, 0.15);
|
|
}
|
|
|
|
|
|
|
|
/* Google 登录区域 */
|
|
.google-login-section {
|
|
margin-bottom: 24px;
|
|
}
|
|
|
|
/* 分隔线 */
|
|
.divider {
|
|
position: relative;
|
|
margin: 32px 0;
|
|
text-align: center;
|
|
}
|
|
|
|
.divider::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 0;
|
|
right: 0;
|
|
height: 1px;
|
|
background: linear-gradient(90deg,
|
|
transparent,
|
|
rgba(139, 92, 246, 0.3),
|
|
transparent);
|
|
}
|
|
|
|
.divider-text {
|
|
padding: 0 16px;
|
|
color: #6B7280;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* 邮箱登录区域 */
|
|
.email-login-section {
|
|
margin-bottom: 32px;
|
|
}
|
|
|
|
/* 角色信息展示区域 */
|
|
.role-info-section {
|
|
border-top: 1px solid rgba(139, 92, 246, 0.1);
|
|
padding-top: 24px;
|
|
margin-top: 24px;
|
|
}
|
|
|
|
/* 角色信息卡片基础样式 */
|
|
.role-info-card {
|
|
background: rgba(107, 70, 193, 0.03);
|
|
border: 1px solid rgba(107, 70, 193, 0.1);
|
|
border-radius: 16px;
|
|
padding: 20px;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
/* 暗色主题适配 */
|
|
html.dark .login-background {
|
|
background: linear-gradient(135deg,
|
|
#1a1625 0%,
|
|
#2d1b69 25%,
|
|
#3b2f7e 50%,
|
|
#4c3f91 75%,
|
|
#1f2937 100%);
|
|
}
|
|
|
|
html.dark .login-card {
|
|
background: rgba(17, 24, 39, 0.95);
|
|
border-color: rgba(139, 92, 246, 0.3);
|
|
color: #f3f4f6;
|
|
}
|
|
|
|
html.dark .divider-text {
|
|
color: #9ca3af;
|
|
}
|
|
|
|
html.dark .divider-line {
|
|
background: linear-gradient(to right, transparent, rgba(139, 92, 246, 0.3), transparent);
|
|
}
|
|
|
|
html.dark .role-info-card {
|
|
background: rgba(139, 92, 246, 0.08);
|
|
border-color: rgba(139, 92, 246, 0.2);
|
|
}
|
|
|
|
html.dark .role-info-card:hover {
|
|
background: rgba(139, 92, 246, 0.12);
|
|
border-color: rgba(139, 92, 246, 0.3);
|
|
}
|
|
|
|
html.dark .role-icon {
|
|
color: #a78bfa;
|
|
}
|
|
|
|
html.dark .role-info-title {
|
|
color: #f3f4f6;
|
|
}
|
|
|
|
html.dark .role-description {
|
|
color: #d1d5db;
|
|
}
|
|
|
|
html.dark .error-message {
|
|
background: rgba(239, 68, 68, 0.1);
|
|
border-color: rgba(239, 68, 68, 0.2);
|
|
color: #fca5a5;
|
|
}
|
|
|
|
html.dark .error-icon {
|
|
color: #f87171;
|
|
}
|
|
|
|
/* 暗色主题下的角色徽章 */
|
|
html.dark .role-badge.creator {
|
|
background: linear-gradient(135deg, #7c3aed, #a78bfa);
|
|
}
|
|
|
|
html.dark .role-badge.admin {
|
|
background: linear-gradient(135deg, #059669, #10b981);
|
|
}
|
|
|
|
html.dark .role-badge.viewer {
|
|
background: linear-gradient(135deg, #6b7280, #9ca3af);
|
|
}
|
|
|
|
|
|
|
|
/* 暗色主题下的所有文本优化 */
|
|
html.dark * {
|
|
scrollbar-color: rgba(139, 92, 246, 0.5) rgba(17, 24, 39, 0.8);
|
|
}
|
|
|
|
/* 确保滚动条样式在暗色主题下正确显示 */
|
|
html.dark ::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
html.dark ::-webkit-scrollbar-track {
|
|
background: rgba(17, 24, 39, 0.8);
|
|
}
|
|
|
|
html.dark ::-webkit-scrollbar-thumb {
|
|
background: rgba(139, 92, 246, 0.5);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
html.dark ::-webkit-scrollbar-thumb:hover {
|
|
background: rgba(139, 92, 246, 0.7);
|
|
}
|
|
|
|
.role-info-card:hover {
|
|
background: rgba(107, 70, 193, 0.05);
|
|
border-color: rgba(107, 70, 193, 0.2);
|
|
transform: translateY(-1px);
|
|
box-shadow: 0 4px 12px rgba(107, 70, 193, 0.15);
|
|
}
|
|
|
|
/* 大屏幕桌面端角色信息优化 */
|
|
@media (min-width: 1200px) {
|
|
.role-info-section {
|
|
padding-top: 32px;
|
|
margin-top: 32px;
|
|
}
|
|
|
|
.role-info-card {
|
|
padding: 24px;
|
|
border-radius: 20px;
|
|
}
|
|
|
|
.role-info-header {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.role-list {
|
|
gap: 16px;
|
|
}
|
|
|
|
.role-item {
|
|
padding: 12px 0;
|
|
}
|
|
|
|
.role-badge {
|
|
padding: 8px 16px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.role-description {
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
|
|
/* 平板端角色信息优化 */
|
|
@media (max-width: 1199px) and (min-width: 768px) {
|
|
.role-info-section {
|
|
padding-top: 20px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.role-info-card {
|
|
padding: 18px;
|
|
border-radius: 16px;
|
|
}
|
|
|
|
.role-info-header {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.role-list {
|
|
gap: 12px;
|
|
}
|
|
|
|
.role-item {
|
|
padding: 8px 0;
|
|
}
|
|
|
|
.role-badge {
|
|
padding: 6px 12px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.role-description {
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
|
|
/* 移动端角色信息优化 */
|
|
@media (max-width: 767px) {
|
|
.role-info-section {
|
|
padding-top: 16px;
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.role-info-card {
|
|
padding: 16px;
|
|
border-radius: 12px;
|
|
background: rgba(107, 70, 193, 0.04);
|
|
}
|
|
|
|
.role-info-header {
|
|
margin-bottom: 14px;
|
|
gap: 6px;
|
|
}
|
|
|
|
.role-icon {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.role-info-title {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.role-list {
|
|
gap: 10px;
|
|
}
|
|
|
|
.role-item {
|
|
padding: 6px 0;
|
|
}
|
|
|
|
.role-badge {
|
|
padding: 4px 10px;
|
|
font-size: 11px;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
.role-description {
|
|
font-size: 12px;
|
|
line-height: 1.4;
|
|
}
|
|
}
|
|
|
|
.role-info-header {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.role-icon {
|
|
color: #6B46C1;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.role-info-title {
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: #374151;
|
|
margin: 0;
|
|
}
|
|
|
|
.role-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
}
|
|
|
|
.role-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
padding: 8px 0;
|
|
}
|
|
|
|
.role-badge {
|
|
align-self: flex-start;
|
|
padding: 6px 12px;
|
|
border-radius: 16px;
|
|
font-size: 12px;
|
|
font-weight: 600;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.5px;
|
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.role-item:hover .role-badge {
|
|
transform: translateX(2px);
|
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
.role-badge.creator {
|
|
background: linear-gradient(135deg, #6B46C1, #8B5CF6);
|
|
color: white;
|
|
}
|
|
|
|
.role-badge.admin {
|
|
background: linear-gradient(135deg, #10B981, #059669);
|
|
color: white;
|
|
}
|
|
|
|
.role-badge.viewer {
|
|
background: linear-gradient(135deg, #F59E0B, #D97706);
|
|
color: white;
|
|
}
|
|
|
|
.role-description {
|
|
font-size: 13px;
|
|
color: #6B7280;
|
|
line-height: 1.5;
|
|
margin: 0;
|
|
padding-left: 4px;
|
|
}
|
|
|
|
/* 错误消息 */
|
|
.error-message {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
background: rgba(239, 68, 68, 0.1);
|
|
border: 1px solid rgba(239, 68, 68, 0.2);
|
|
border-radius: 12px;
|
|
padding: 12px 16px;
|
|
color: #EF4444;
|
|
font-size: 14px;
|
|
margin-top: 20px;
|
|
animation: shake 0.5s ease-in-out;
|
|
}
|
|
|
|
@keyframes shake {
|
|
0%, 100% { transform: translateX(0); }
|
|
25% { transform: translateX(-5px); }
|
|
75% { transform: translateX(5px); }
|
|
}
|
|
|
|
.error-icon {
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
/* 响应式设计断点 */
|
|
/* 大屏幕桌面端 (1200px+) */
|
|
@media (min-width: 1200px) {
|
|
.login-container {
|
|
max-width: 480px;
|
|
}
|
|
|
|
.login-card {
|
|
padding: 56px 48px;
|
|
border-radius: 28px;
|
|
box-shadow:
|
|
0 25px 30px -5px rgba(0, 0, 0, 0.12),
|
|
0 15px 15px -5px rgba(0, 0, 0, 0.08),
|
|
0 0 0 1px rgba(139, 92, 246, 0.12);
|
|
}
|
|
|
|
.login-card:hover {
|
|
transform: translateY(-3px);
|
|
box-shadow:
|
|
0 30px 35px -5px rgba(0, 0, 0, 0.15),
|
|
0 20px 20px -5px rgba(0, 0, 0, 0.1),
|
|
0 0 0 1px rgba(139, 92, 246, 0.15);
|
|
}
|
|
}
|
|
|
|
/* 平板端横屏和大平板竖屏 (1024px) */
|
|
@media (max-width: 1199px) and (min-width: 1024px) {
|
|
.login-container {
|
|
max-width: 420px;
|
|
padding: 24px;
|
|
}
|
|
|
|
.login-card {
|
|
padding: 44px 36px;
|
|
border-radius: 24px;
|
|
backdrop-filter: blur(25px);
|
|
}
|
|
|
|
.login-card:hover {
|
|
transform: translateY(-2px);
|
|
}
|
|
|
|
.google-login-section {
|
|
margin-bottom: 28px;
|
|
}
|
|
|
|
.divider {
|
|
margin: 36px 0;
|
|
}
|
|
|
|
.email-login-section {
|
|
margin-bottom: 36px;
|
|
}
|
|
|
|
.role-info-section {
|
|
padding-top: 28px;
|
|
margin-top: 28px;
|
|
}
|
|
}
|
|
|
|
/* 平板端 (768px - 1023px) */
|
|
@media (max-width: 1023px) and (min-width: 768px) {
|
|
.login-container {
|
|
max-width: 92%;
|
|
padding: 20px;
|
|
}
|
|
|
|
.login-card {
|
|
padding: 36px 32px;
|
|
}
|
|
|
|
.google-login-section {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.divider {
|
|
margin: 28px 0;
|
|
}
|
|
|
|
.email-login-section {
|
|
margin-bottom: 28px;
|
|
}
|
|
|
|
.role-info-section {
|
|
padding-top: 20px;
|
|
margin-top: 20px;
|
|
}
|
|
|
|
.role-info-card {
|
|
padding: 16px;
|
|
}
|
|
}
|
|
|
|
/* 移动端 (481px - 767px) */
|
|
@media (max-width: 767px) and (min-width: 481px) {
|
|
.login-container {
|
|
max-width: 94%;
|
|
padding: 16px;
|
|
}
|
|
|
|
.login-card {
|
|
padding: 32px 28px;
|
|
}
|
|
|
|
.role-item {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
gap: 6px;
|
|
}
|
|
|
|
.role-badge {
|
|
align-self: flex-start;
|
|
}
|
|
}
|
|
|
|
/* 小屏幕手机端 (320px - 480px) */
|
|
@media (max-width: 480px) {
|
|
.login-container {
|
|
max-width: 96%;
|
|
padding: 12px;
|
|
}
|
|
|
|
.login-card {
|
|
padding: 20px 16px;
|
|
border-radius: 16px;
|
|
backdrop-filter: blur(15px);
|
|
background: rgba(255, 255, 255, 0.98);
|
|
}
|
|
|
|
.login-card:hover {
|
|
transform: none;
|
|
}
|
|
|
|
.google-login-section {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.divider {
|
|
margin: 20px 0;
|
|
}
|
|
|
|
.email-login-section {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.role-info-section {
|
|
padding-top: 16px;
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.role-info-card {
|
|
padding: 14px;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.role-item {
|
|
flex-direction: column;
|
|
align-items: center;
|
|
gap: 6px;
|
|
text-align: center;
|
|
padding: 6px 0;
|
|
}
|
|
|
|
.role-badge {
|
|
align-self: center;
|
|
padding: 4px 10px;
|
|
font-size: 11px;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.role-description {
|
|
text-align: center;
|
|
padding-left: 0;
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* 超小屏幕优化 (320px - 380px) */
|
|
@media (max-width: 380px) {
|
|
.login-container {
|
|
max-width: 98%;
|
|
padding: 8px;
|
|
}
|
|
|
|
.login-card {
|
|
padding: 16px 12px;
|
|
border-radius: 12px;
|
|
}
|
|
|
|
.google-login-section {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
.divider {
|
|
margin: 16px 0;
|
|
}
|
|
|
|
.email-login-section {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.role-info-section {
|
|
padding-top: 12px;
|
|
margin-top: 12px;
|
|
}
|
|
|
|
.role-info-card {
|
|
padding: 12px;
|
|
}
|
|
|
|
.role-description {
|
|
font-size: 11px;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* 右上角控制组件样式 */
|
|
.top-right-controls {
|
|
position: fixed;
|
|
top: 24px;
|
|
right: 24px;
|
|
z-index: 1000;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
align-items: center;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 容器包装控制组件 */
|
|
.controls-container {
|
|
display: flex;
|
|
gap: 12px;
|
|
margin-left: auto;
|
|
}
|
|
|
|
/* 确保组件对齐 */
|
|
.top-right-controls .theme-toggle,
|
|
.top-right-controls .language-toggle {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
/* 统一组件高度,确保对齐 */
|
|
.top-right-controls .theme-toggle .theme-toggle-btn,
|
|
.top-right-controls .language-toggle .language-toggle__button {
|
|
height: 48px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-width: 48px;
|
|
}
|
|
|
|
/* 大屏幕桌面端 (1200px+) */
|
|
@media (min-width: 1200px) {
|
|
.top-right-controls {
|
|
padding: 0 48px;
|
|
}
|
|
|
|
.top-right-controls .theme-toggle .theme-toggle-btn,
|
|
.top-right-controls .language-toggle .language-toggle__button {
|
|
height: 52px;
|
|
min-width: 52px;
|
|
}
|
|
}
|
|
|
|
/* ==================== 暗色主题样式 ==================== */
|
|
|
|
/* 暗色主题背景 */
|
|
html.dark .login-background {
|
|
background: linear-gradient(135deg,
|
|
#1a1a2e 0%,
|
|
#16213e 25%,
|
|
#0f3460 50%,
|
|
#533483 75%,
|
|
#2d1b69 100%);
|
|
/* 优化性能,避免滚动条 */
|
|
background-attachment: fixed;
|
|
}
|
|
|
|
/* 暗色主题登录卡片 */
|
|
html.dark .login-card {
|
|
background: rgba(17, 24, 39, 0.95);
|
|
border: 1px solid rgba(139, 92, 246, 0.2);
|
|
backdrop-filter: blur(20px);
|
|
}
|
|
|
|
html.dark .login-card:hover {
|
|
border-color: rgba(139, 92, 246, 0.4);
|
|
box-shadow:
|
|
0 25px 50px rgba(0, 0, 0, 0.5),
|
|
0 0 0 1px rgba(139, 92, 246, 0.3),
|
|
inset 0 1px 0 rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
/* 暗色主题分割线 */
|
|
html.dark .divider-line {
|
|
background: linear-gradient(
|
|
to right,
|
|
transparent,
|
|
rgba(139, 92, 246, 0.3),
|
|
rgba(139, 92, 246, 0.6),
|
|
rgba(139, 92, 246, 0.3),
|
|
transparent
|
|
);
|
|
}
|
|
|
|
html.dark .divider-text {
|
|
color: #d1d5db;
|
|
background: rgba(17, 24, 39, 0.8);
|
|
}
|
|
|
|
/* 暗色主题角色信息卡片 */
|
|
html.dark .role-info-card {
|
|
background: rgba(31, 41, 55, 0.8);
|
|
border: 1px solid rgba(139, 92, 246, 0.2);
|
|
}
|
|
|
|
html.dark .role-info-title {
|
|
color: #f3f4f6;
|
|
}
|
|
|
|
html.dark .role-description {
|
|
color: #d1d5db;
|
|
}
|
|
|
|
/* 暗色主题角色徽章 */
|
|
html.dark .role-badge.creator {
|
|
background: linear-gradient(135deg, #dc2626, #ef4444);
|
|
color: white;
|
|
}
|
|
|
|
html.dark .role-badge.admin {
|
|
background: linear-gradient(135deg, #7c3aed, #8b5cf6);
|
|
color: white;
|
|
}
|
|
|
|
html.dark .role-badge.viewer {
|
|
background: linear-gradient(135deg, #059669, #10b981);
|
|
color: white;
|
|
}
|
|
|
|
/* 暗色主题错误提示 */
|
|
html.dark .error-message {
|
|
background: rgba(127, 29, 29, 0.8);
|
|
border: 1px solid rgba(239, 68, 68, 0.3);
|
|
color: #fca5a5;
|
|
}
|
|
|
|
html.dark .error-icon {
|
|
color: #ef4444;
|
|
}
|
|
|
|
/* 忘记密码和注册链接样式 */
|
|
.auth-links {
|
|
margin-top: 24px;
|
|
padding-top: 16px;
|
|
border-top: 1px solid rgba(139, 92, 246, 0.1);
|
|
}
|
|
|
|
.auth-links-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
gap: 16px;
|
|
}
|
|
|
|
.auth-link {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
background: none;
|
|
border: none;
|
|
color: #6B46C1;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
padding: 8px 12px;
|
|
border-radius: 8px;
|
|
transition: all 0.2s ease;
|
|
text-decoration: none;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.auth-link:hover {
|
|
background: rgba(107, 70, 193, 0.1);
|
|
color: #5B21B6;
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.auth-link:active {
|
|
transform: translateY(0);
|
|
}
|
|
|
|
.link-icon {
|
|
font-size: 14px;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.forgot-password-link:hover .link-icon {
|
|
color: #8B5CF6;
|
|
}
|
|
|
|
.register-link:hover .link-icon {
|
|
color: #8B5CF6;
|
|
}
|
|
|
|
/* 暗色主题下的链接样式 */
|
|
html.dark .auth-links {
|
|
border-top-color: rgba(139, 92, 246, 0.2);
|
|
}
|
|
|
|
html.dark .auth-link {
|
|
color: #a78bfa;
|
|
}
|
|
|
|
html.dark .auth-link:hover {
|
|
background: rgba(139, 92, 246, 0.2);
|
|
color: #8b5cf6;
|
|
}
|
|
|
|
html.dark .link-icon {
|
|
color: #9ca3af;
|
|
}
|
|
|
|
html.dark .forgot-password-link:hover .link-icon,
|
|
html.dark .register-link:hover .link-icon {
|
|
color: #8b5cf6;
|
|
}
|
|
|
|
/* 暗色主题滚动条优化 */
|
|
html.dark ::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
|
|
html.dark ::-webkit-scrollbar-track {
|
|
background: rgba(17, 24, 39, 0.8);
|
|
}
|
|
|
|
html.dark ::-webkit-scrollbar-thumb {
|
|
background: rgba(139, 92, 246, 0.5);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
html.dark ::-webkit-scrollbar-thumb:hover {
|
|
background: rgba(139, 92, 246, 0.7);
|
|
}
|
|
@media (max-width: 480px) {
|
|
html.dark .login-card {
|
|
background: rgba(17, 24, 39, 0.98);
|
|
}
|
|
}
|
|
|
|
/* 忘记密码和注册链接响应式设计 */
|
|
@media (max-width: 480px) {
|
|
.auth-links {
|
|
margin-top: 20px;
|
|
padding-top: 14px;
|
|
}
|
|
|
|
.auth-links-row {
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.auth-link {
|
|
justify-content: center;
|
|
padding: 10px 16px;
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 360px) {
|
|
.auth-links {
|
|
margin-top: 16px;
|
|
padding-top: 12px;
|
|
}
|
|
|
|
.auth-link {
|
|
padding: 8px 12px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.link-icon {
|
|
font-size: 13px;
|
|
}
|
|
}
|
|
|
|
/* 平板端横屏和大平板竖屏 (1024px) */
|
|
@media (max-width: 1199px) and (min-width: 1024px) {
|
|
.top-right-controls {
|
|
top: 20px;
|
|
right: 20px;
|
|
}
|
|
|
|
.top-right-controls .theme-toggle .theme-toggle-btn,
|
|
.top-right-controls .language-toggle .language-toggle__button {
|
|
height: 50px;
|
|
min-width: 50px;
|
|
}
|
|
}
|
|
|
|
/* 平板端 (768px - 1023px) */
|
|
@media (max-width: 1023px) and (min-width: 768px) {
|
|
.top-right-controls {
|
|
top: 16px;
|
|
right: 16px;
|
|
}
|
|
|
|
.controls-container {
|
|
gap: 8px;
|
|
}
|
|
|
|
.top-right-controls .theme-toggle .theme-toggle-btn,
|
|
.top-right-controls .language-toggle .language-toggle__button {
|
|
height: 44px;
|
|
min-width: 44px;
|
|
transform: scale(0.95);
|
|
}
|
|
}
|
|
|
|
/* 移动端 (481px - 767px) */
|
|
@media (max-width: 767px) and (min-width: 481px) {
|
|
.top-right-controls {
|
|
top: 12px;
|
|
right: 12px;
|
|
}
|
|
|
|
.controls-container {
|
|
gap: 6px;
|
|
}
|
|
|
|
.top-right-controls .theme-toggle .theme-toggle-btn,
|
|
.top-right-controls .language-toggle .language-toggle__button {
|
|
height: 40px;
|
|
min-width: 40px;
|
|
transform: scale(0.9);
|
|
}
|
|
}
|
|
|
|
/* 小屏幕手机端 (320px - 480px) */
|
|
@media (max-width: 480px) {
|
|
.top-right-controls {
|
|
top: 8px;
|
|
right: 8px;
|
|
}
|
|
|
|
.controls-container {
|
|
gap: 4px;
|
|
}
|
|
|
|
.top-right-controls .theme-toggle .theme-toggle-btn,
|
|
.top-right-controls .language-toggle .language-toggle__button {
|
|
height: 36px;
|
|
min-width: 36px;
|
|
transform: scale(0.85);
|
|
}
|
|
|
|
/* 在非常小的屏幕上,可以考虑隐藏其中一个组件 */
|
|
@media (max-width: 360px) {
|
|
.controls-container {
|
|
gap: 2px;
|
|
}
|
|
|
|
.top-right-controls .theme-toggle .theme-toggle-btn,
|
|
.top-right-controls .language-toggle .language-toggle__button {
|
|
height: 34px;
|
|
min-width: 34px;
|
|
transform: scale(0.8);
|
|
}
|
|
}
|
|
}
|
|
</style> |