|
|
@@ -0,0 +1,809 @@
|
|
|
+<template>
|
|
|
+ <div class="login-container">
|
|
|
+ <!-- 背景装饰元素 -->
|
|
|
+ <div class="background-shapes">
|
|
|
+ <div class="shape shape-1"></div>
|
|
|
+ <div class="shape shape-2"></div>
|
|
|
+ <div class="shape shape-3"></div>
|
|
|
+ <div class="shape shape-4"></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="login-content">
|
|
|
+ <!-- 左侧品牌区域 -->
|
|
|
+ <div class="brand-section">
|
|
|
+ <div class="brand-content">
|
|
|
+ <div class="logo">
|
|
|
+ <i class="el-icon-star-filled logo-icon"></i>
|
|
|
+ <h1 class="brand-name">Your Logo</h1>
|
|
|
+ </div>
|
|
|
+ <h2 class="brand-title">
|
|
|
+ {{ isLogin ? '欢迎回来' : '加入我们' }}
|
|
|
+ </h2>
|
|
|
+ <p class="brand-description">
|
|
|
+ {{ isLogin
|
|
|
+ ? '请登录您的账户,继续享受我们的服务'
|
|
|
+ : '创建新账户,开启全新的体验旅程'
|
|
|
+ }}
|
|
|
+ </p>
|
|
|
+ <div class="feature-list">
|
|
|
+ <div class="feature-item">
|
|
|
+ <i class="el-icon-check feature-icon"></i>
|
|
|
+ <span>安全可靠的数据保护</span>
|
|
|
+ </div>
|
|
|
+ <div class="feature-item">
|
|
|
+ <i class="el-icon-check feature-icon"></i>
|
|
|
+ <span>简单易用的操作界面</span>
|
|
|
+ </div>
|
|
|
+ <div class="feature-item">
|
|
|
+ <i class="el-icon-check feature-icon"></i>
|
|
|
+ <span>全天候的技术支持</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 右侧表单区域 -->
|
|
|
+ <div class="form-section">
|
|
|
+ <div class="form-wrapper">
|
|
|
+ <!-- 移动端品牌头 -->
|
|
|
+ <div class="mobile-header">
|
|
|
+ <div class="mobile-logo">
|
|
|
+ <i class="el-icon-star-filled"></i>
|
|
|
+ <span>Your Logo</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="form-header">
|
|
|
+ <h1>{{ isLogin ? '用户登录' : '用户注册' }}</h1>
|
|
|
+ <p>{{ isLogin ? '请输入您的账户信息' : '请填写注册信息' }}</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 登录表单 -->
|
|
|
+ <el-form
|
|
|
+ v-if="isLogin"
|
|
|
+ ref="loginFormRef"
|
|
|
+ :model="loginForm"
|
|
|
+ :rules="loginRules"
|
|
|
+ class="auth-form"
|
|
|
+ size="large"
|
|
|
+ @submit.prevent="handleLogin"
|
|
|
+ >
|
|
|
+ <el-form-item prop="userAccount">
|
|
|
+ <el-input
|
|
|
+ v-model="loginForm.userAccount"
|
|
|
+ placeholder="请输入用户账号"
|
|
|
+ :prefix-icon="User"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item prop="userPassword">
|
|
|
+ <el-input
|
|
|
+ v-model="loginForm.userPassword"
|
|
|
+ type="password"
|
|
|
+ placeholder="请输入用户密码"
|
|
|
+ :prefix-icon="Lock"
|
|
|
+ show-password
|
|
|
+ clearable
|
|
|
+ @keyup.enter="handleLogin"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div class="form-options">
|
|
|
+ <el-checkbox v-model="rememberMe">记住我</el-checkbox>
|
|
|
+ <el-button type="text" class="forgot-password">忘记密码?</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ :loading="loading"
|
|
|
+ @click="handleLogin"
|
|
|
+ class="auth-btn"
|
|
|
+ >
|
|
|
+ {{ loading ? '登录中...' : '登录' }}
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div class="divider">
|
|
|
+ <span>或</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="social-login">
|
|
|
+ <el-button class="social-btn wechat">
|
|
|
+ <i class="el-icon-chat-dot-round"></i>
|
|
|
+ 微信登录
|
|
|
+ </el-button>
|
|
|
+ <el-button class="social-btn qq">
|
|
|
+ <i class="el-icon-chat-line-round"></i>
|
|
|
+ QQ登录
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <!-- 注册表单 -->
|
|
|
+ <el-form
|
|
|
+ v-else
|
|
|
+ ref="registerFormRef"
|
|
|
+ :model="registerForm"
|
|
|
+ :rules="registerRules"
|
|
|
+ class="auth-form"
|
|
|
+ size="large"
|
|
|
+ @submit.prevent="handleRegister"
|
|
|
+ >
|
|
|
+ <el-form-item prop="userAccount">
|
|
|
+ <el-input
|
|
|
+ v-model="registerForm.userAccount"
|
|
|
+ placeholder="请输入用户账号"
|
|
|
+ :prefix-icon="User"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item prop="userPassword">
|
|
|
+ <el-input
|
|
|
+ v-model="registerForm.userPassword"
|
|
|
+ type="password"
|
|
|
+ placeholder="请输入用户密码"
|
|
|
+ :prefix-icon="Lock"
|
|
|
+ show-password
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item prop="userName">
|
|
|
+ <el-input
|
|
|
+ v-model="registerForm.userName"
|
|
|
+ placeholder="请输入用户名称"
|
|
|
+ :prefix-icon="EditPen"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ :loading="loading"
|
|
|
+ @click="handleRegister"
|
|
|
+ class="auth-btn"
|
|
|
+ >
|
|
|
+ {{ loading ? '注册中...' : '注册' }}
|
|
|
+ </el-button>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <div class="agreement">
|
|
|
+ <el-checkbox v-model="agreeTerms">
|
|
|
+ 我已阅读并同意
|
|
|
+ <el-button type="text" class="link-btn">服务协议</el-button>
|
|
|
+ 和
|
|
|
+ <el-button type="text" class="link-btn">隐私政策</el-button>
|
|
|
+ </el-checkbox>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+ <div class="form-footer">
|
|
|
+ <span class="switch-text">
|
|
|
+ {{ isLogin ? '还没有账户?' : '已有账户?' }}
|
|
|
+ </span>
|
|
|
+ <el-button type="text" @click="toggleForm" class="switch-btn">
|
|
|
+ {{ isLogin ? '立即注册' : '立即登录' }}
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref, reactive, onMounted } from 'vue'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+import { ElMessage } from 'element-plus'
|
|
|
+import { User, Lock, EditPen } from '@element-plus/icons-vue'
|
|
|
+import { login, register } from '/src/commom/api/user.js'
|
|
|
+
|
|
|
+const router = useRouter()
|
|
|
+
|
|
|
+// 响应式数据
|
|
|
+const isLogin = ref(true)
|
|
|
+const loading = ref(false)
|
|
|
+const rememberMe = ref(false)
|
|
|
+const agreeTerms = ref(false)
|
|
|
+const loginFormRef = ref()
|
|
|
+const registerFormRef = ref()
|
|
|
+
|
|
|
+// 表单数据
|
|
|
+const loginForm = reactive({
|
|
|
+ userAccount: '',
|
|
|
+ userPassword: ''
|
|
|
+})
|
|
|
+
|
|
|
+const registerForm = reactive({
|
|
|
+ userAccount: '',
|
|
|
+ userPassword: '',
|
|
|
+ userName: ''
|
|
|
+})
|
|
|
+
|
|
|
+// 表单验证规则
|
|
|
+const loginRules = reactive({
|
|
|
+ userAccount: [
|
|
|
+ { required: true, message: '请输入用户账号', trigger: 'blur' },
|
|
|
+ { min: 4, max: 20, message: '账号长度在 4 到 20 个字符', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ userPassword: [
|
|
|
+ { required: true, message: '请输入用户密码', trigger: 'blur' },
|
|
|
+ { min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
|
|
|
+ ]
|
|
|
+})
|
|
|
+
|
|
|
+const registerRules = reactive({
|
|
|
+ userAccount: [
|
|
|
+ { required: true, message: '请输入用户账号', trigger: 'blur' },
|
|
|
+ { min: 4, max: 20, message: '账号长度在 4 到 20 个字符', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ userPassword: [
|
|
|
+ { required: true, message: '请输入用户密码', trigger: 'blur' },
|
|
|
+ { min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ userName: [
|
|
|
+ { required: true, message: '请输入用户名称', trigger: 'blur' },
|
|
|
+ { min: 2, max: 20, message: '名称长度在 2 到 20 个字符', trigger: 'blur' }
|
|
|
+ ]
|
|
|
+})
|
|
|
+
|
|
|
+// 方法
|
|
|
+const toggleForm = () => {
|
|
|
+ isLogin.value = !isLogin.value
|
|
|
+ if (loginFormRef.value) loginFormRef.value.resetFields()
|
|
|
+ if (registerFormRef.value) registerFormRef.value.resetFields()
|
|
|
+}
|
|
|
+
|
|
|
+const handleLogin = async () => {
|
|
|
+ if (!loginFormRef.value) return
|
|
|
+
|
|
|
+ try {
|
|
|
+ const valid = await loginFormRef.value.validate()
|
|
|
+ if (valid) {
|
|
|
+ loading.value = true
|
|
|
+ // 这里调用登录API
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 1500)) // 模拟API调用
|
|
|
+ ElMessage.success('登录成功!')
|
|
|
+ router.push('/')
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('登录失败,请检查账号密码')
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const handleRegister = async () => {
|
|
|
+ if (!registerFormRef.value) return
|
|
|
+
|
|
|
+ if (!agreeTerms.value) {
|
|
|
+ ElMessage.warning('请同意服务协议和隐私政策')
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const valid = await registerFormRef.value.validate()
|
|
|
+ if (valid) {
|
|
|
+ loading.value = true
|
|
|
+ // 这里调用注册API
|
|
|
+ await new Promise(resolve => setTimeout(resolve, 1500)) // 模拟API调用
|
|
|
+ ElMessage.success('注册成功!')
|
|
|
+ toggleForm()
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ ElMessage.error('注册失败,请稍后重试')
|
|
|
+ } finally {
|
|
|
+ loading.value = false
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ const token = localStorage.getItem('token')
|
|
|
+ if (token) {
|
|
|
+ router.push('/')
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.login-container {
|
|
|
+ min-height: 100vh;
|
|
|
+ min-width: 100vw;
|
|
|
+ height: 100vh;
|
|
|
+ width: 100vw;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.background-shapes {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ pointer-events: none;
|
|
|
+ z-index: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.shape {
|
|
|
+ position: absolute;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: rgba(255, 255, 255, 0.1);
|
|
|
+}
|
|
|
+
|
|
|
+.shape-1 {
|
|
|
+ width: 300px;
|
|
|
+ height: 300px;
|
|
|
+ top: -150px;
|
|
|
+ right: -150px;
|
|
|
+}
|
|
|
+
|
|
|
+.shape-2 {
|
|
|
+ width: 200px;
|
|
|
+ height: 200px;
|
|
|
+ bottom: -100px;
|
|
|
+ left: -100px;
|
|
|
+}
|
|
|
+
|
|
|
+.shape-3 {
|
|
|
+ width: 150px;
|
|
|
+ height: 150px;
|
|
|
+ top: 50%;
|
|
|
+ left: 10%;
|
|
|
+}
|
|
|
+
|
|
|
+.shape-4 {
|
|
|
+ width: 100px;
|
|
|
+ height: 100px;
|
|
|
+ bottom: 20%;
|
|
|
+ right: 10%;
|
|
|
+}
|
|
|
+
|
|
|
+.login-content {
|
|
|
+ display: flex;
|
|
|
+ width: 95%;
|
|
|
+ max-width: 1200px;
|
|
|
+ height: 90vh;
|
|
|
+ max-height: 800px;
|
|
|
+ background: white;
|
|
|
+ border-radius: 20px;
|
|
|
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1);
|
|
|
+ overflow: hidden;
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+/* 品牌区域样式 */
|
|
|
+.brand-section {
|
|
|
+ flex: 1;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ color: white;
|
|
|
+ padding: 60px 40px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.brand-section::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ bottom: 0;
|
|
|
+ background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grid" width="10" height="10" patternUnits="userSpaceOnUse"><path d="M 10 0 L 0 0 0 10" fill="none" stroke="rgba(255,255,255,0.1)" stroke-width="1"/></pattern></defs><rect width="100" height="100" fill="url(%23grid)"/></svg>');
|
|
|
+}
|
|
|
+
|
|
|
+.brand-content {
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
+ text-align: center;
|
|
|
+ max-width: 400px;
|
|
|
+}
|
|
|
+
|
|
|
+.logo {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 12px;
|
|
|
+ margin-bottom: 40px;
|
|
|
+}
|
|
|
+
|
|
|
+.logo-icon {
|
|
|
+ font-size: 32px;
|
|
|
+ color: #ffd700;
|
|
|
+}
|
|
|
+
|
|
|
+.brand-name {
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: 700;
|
|
|
+ margin: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.brand-title {
|
|
|
+ font-size: 32px;
|
|
|
+ font-weight: 700;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ line-height: 1.2;
|
|
|
+}
|
|
|
+
|
|
|
+.brand-description {
|
|
|
+ font-size: 16px;
|
|
|
+ line-height: 1.6;
|
|
|
+ margin-bottom: 40px;
|
|
|
+ opacity: 0.9;
|
|
|
+}
|
|
|
+
|
|
|
+.feature-list {
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+
|
|
|
+.feature-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+ margin-bottom: 16px;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.feature-icon {
|
|
|
+ color: #ffd700;
|
|
|
+ font-size: 16px;
|
|
|
+}
|
|
|
+
|
|
|
+/* 表单区域样式 */
|
|
|
+.form-section {
|
|
|
+ flex: 1;
|
|
|
+ padding: 40px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background: white;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.form-wrapper {
|
|
|
+ width: 100%;
|
|
|
+ max-width: 400px;
|
|
|
+}
|
|
|
+
|
|
|
+.mobile-header {
|
|
|
+ display: none;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 8px;
|
|
|
+ margin-bottom: 30px;
|
|
|
+ color: #667eea;
|
|
|
+ font-weight: 600;
|
|
|
+ font-size: 18px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-header {
|
|
|
+ text-align: center;
|
|
|
+ margin-bottom: 40px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-header h1 {
|
|
|
+ font-size: 28px;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #333;
|
|
|
+ margin-bottom: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-header p {
|
|
|
+ color: #666;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.auth-form {
|
|
|
+ width: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-input) {
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-input__wrapper) {
|
|
|
+ border-radius: 10px;
|
|
|
+ padding: 12px 16px;
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-input__inner) {
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-options {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.forgot-password {
|
|
|
+ color: #667eea;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.auth-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 48px;
|
|
|
+ border-radius: 10px;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
|
+ border: none;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.auth-btn:hover {
|
|
|
+ transform: translateY(-1px);
|
|
|
+ box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
|
|
|
+}
|
|
|
+
|
|
|
+.auth-btn:active {
|
|
|
+ transform: translateY(0);
|
|
|
+}
|
|
|
+
|
|
|
+.divider {
|
|
|
+ position: relative;
|
|
|
+ text-align: center;
|
|
|
+ margin: 30px 0;
|
|
|
+ color: #999;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.divider::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ height: 1px;
|
|
|
+ background: #eee;
|
|
|
+}
|
|
|
+
|
|
|
+.divider span {
|
|
|
+ background: white;
|
|
|
+ padding: 0 15px;
|
|
|
+ position: relative;
|
|
|
+}
|
|
|
+
|
|
|
+.social-login {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ gap: 12px;
|
|
|
+ margin-bottom: 30px;
|
|
|
+}
|
|
|
+
|
|
|
+.social-btn {
|
|
|
+ height: 44px;
|
|
|
+ border-radius: 10px;
|
|
|
+ border: 1px solid #e4e7ed;
|
|
|
+ background: white;
|
|
|
+ color: #333;
|
|
|
+ font-size: 14px;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.social-btn:hover {
|
|
|
+ border-color: #667eea;
|
|
|
+ color: #667eea;
|
|
|
+ transform: translateY(-1px);
|
|
|
+}
|
|
|
+
|
|
|
+.agreement {
|
|
|
+ margin-top: 20px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+
|
|
|
+.link-btn {
|
|
|
+ color: #667eea;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-footer {
|
|
|
+ text-align: center;
|
|
|
+ margin-top: 30px;
|
|
|
+ padding-top: 20px;
|
|
|
+ border-top: 1px solid #f0f0f0;
|
|
|
+}
|
|
|
+
|
|
|
+.switch-text {
|
|
|
+ color: #666;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.switch-btn {
|
|
|
+ color: #667eea;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 600;
|
|
|
+ margin-left: 5px;
|
|
|
+ transition: color 0.3s ease;
|
|
|
+}
|
|
|
+
|
|
|
+.switch-btn:hover {
|
|
|
+ color: #764ba2;
|
|
|
+}
|
|
|
+
|
|
|
+/* 响应式设计 */
|
|
|
+@media (max-width: 768px) {
|
|
|
+ .login-container {
|
|
|
+ position: fixed;
|
|
|
+ padding: 0;
|
|
|
+ background: white;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+
|
|
|
+ .login-content {
|
|
|
+ flex-direction: column;
|
|
|
+ border-radius: 0;
|
|
|
+ box-shadow: none;
|
|
|
+ height: auto;
|
|
|
+ min-height: 100vh;
|
|
|
+ width: 100%;
|
|
|
+ max-width: 100%;
|
|
|
+ margin: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .brand-section {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .mobile-header {
|
|
|
+ display: flex;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-section {
|
|
|
+ padding: 40px 24px;
|
|
|
+ height: auto;
|
|
|
+ min-height: 100vh;
|
|
|
+ align-items: flex-start;
|
|
|
+ padding-top: 80px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-wrapper {
|
|
|
+ max-width: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .background-shapes {
|
|
|
+ display: none;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (max-width: 480px) {
|
|
|
+ .form-section {
|
|
|
+ padding: 30px 20px;
|
|
|
+ padding-top: 60px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-header h1 {
|
|
|
+ font-size: 24px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .social-login {
|
|
|
+ grid-template-columns: 1fr;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-options {
|
|
|
+ flex-direction: column;
|
|
|
+ gap: 12px;
|
|
|
+ align-items: flex-start;
|
|
|
+ }
|
|
|
+
|
|
|
+ .brand-title {
|
|
|
+ font-size: 28px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (min-width: 769px) and (max-width: 1024px) {
|
|
|
+ .login-content {
|
|
|
+ max-width: 900px;
|
|
|
+ height: 85vh;
|
|
|
+ }
|
|
|
+
|
|
|
+ .brand-section {
|
|
|
+ padding: 40px 30px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-section {
|
|
|
+ padding: 40px 30px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+@media (min-width: 1025px) and (max-height: 800px) {
|
|
|
+ .login-content {
|
|
|
+ height: 95vh;
|
|
|
+ max-height: 95vh;
|
|
|
+ }
|
|
|
+
|
|
|
+ .brand-section {
|
|
|
+ padding: 40px 30px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-section {
|
|
|
+ padding: 30px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 超大屏幕适配 */
|
|
|
+@media (min-width: 1920px) {
|
|
|
+ .login-content {
|
|
|
+ max-width: 1400px;
|
|
|
+ max-height: 900px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .brand-section {
|
|
|
+ padding: 80px 60px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-section {
|
|
|
+ padding: 60px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .form-header h1 {
|
|
|
+ font-size: 32px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .brand-title {
|
|
|
+ font-size: 36px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 动画效果 */
|
|
|
+.login-container {
|
|
|
+ animation: fadeIn 0.8s ease-out;
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes fadeIn {
|
|
|
+ from {
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+ to {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/* 确保body和html也是全屏 */
|
|
|
+:global(html), :global(body) {
|
|
|
+ margin: 0;
|
|
|
+ padding: 0;
|
|
|
+ height: 100%;
|
|
|
+ width: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+/* 滚动条样式优化 */
|
|
|
+.form-section::-webkit-scrollbar {
|
|
|
+ width: 6px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-section::-webkit-scrollbar-track {
|
|
|
+ background: #f1f1f1;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-section::-webkit-scrollbar-thumb {
|
|
|
+ background: #c1c1c1;
|
|
|
+ border-radius: 3px;
|
|
|
+}
|
|
|
+
|
|
|
+.form-section::-webkit-scrollbar-thumb:hover {
|
|
|
+ background: #a8a8a8;
|
|
|
+}
|
|
|
+</style>
|