|
|
@@ -1,14 +1,8 @@
|
|
|
<template>
|
|
|
<view class="container">
|
|
|
- <!-- 动态背景层 -->
|
|
|
+ <!-- 背景层 -->
|
|
|
<view class="bg-layer">
|
|
|
- <view class="gradient-orb orb-1"></view>
|
|
|
- <view class="gradient-orb orb-2"></view>
|
|
|
- <view class="gradient-orb orb-3"></view>
|
|
|
- <view class="wave-container">
|
|
|
- <view class="wave wave-1"></view>
|
|
|
- <view class="wave wave-2"></view>
|
|
|
- </view>
|
|
|
+ <view class="gradient-orb"></view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 主内容区 -->
|
|
|
@@ -16,35 +10,25 @@
|
|
|
<!-- 品牌展示区 -->
|
|
|
<view class="brand-showcase">
|
|
|
<view class="logo-wrapper">
|
|
|
- <!-- 外层装饰环 -->
|
|
|
- <view class="logo-outer-ring">
|
|
|
- <!-- 内层装饰环 -->
|
|
|
- <view class="logo-inner-ring">
|
|
|
- <!-- 光晕效果 -->
|
|
|
- <view class="logo-glow"></view>
|
|
|
- <!-- Logo主体 -->
|
|
|
- <view class="logo-circle">
|
|
|
- <image class="logo" src="/static/brand-logo.svg" mode="aspectFit"></image>
|
|
|
- </view>
|
|
|
+ <view class="logo-ring">
|
|
|
+ <view class="logo-glow"></view>
|
|
|
+ <view class="logo-circle">
|
|
|
+ <image class="logo" src="/static/brand-logo.svg" mode="aspectFit"></image>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
-
|
|
|
- <view class="brand-text-group">
|
|
|
- <text class="brand-subtitle">AI智能零售柜 · 即拿即走</text>
|
|
|
- </view>
|
|
|
-
|
|
|
+
|
|
|
+ <text class="brand-name">AI零售柜</text>
|
|
|
+ <text class="brand-desc">扫码开门 · 即拿即走</text>
|
|
|
+
|
|
|
<view class="feature-tags">
|
|
|
<view class="tag">
|
|
|
- <text class="tag-icon">⚡</text>
|
|
|
<text class="tag-text">秒级开门</text>
|
|
|
</view>
|
|
|
<view class="tag">
|
|
|
- <text class="tag-icon">🔒</text>
|
|
|
<text class="tag-text">安全支付</text>
|
|
|
</view>
|
|
|
<view class="tag">
|
|
|
- <text class="tag-icon">🤖</text>
|
|
|
<text class="tag-text">AI识别</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -58,38 +42,32 @@
|
|
|
<view class="header-line"></view>
|
|
|
</view>
|
|
|
|
|
|
- <!-- 微信手机号快速登录按钮 -->
|
|
|
<button
|
|
|
- class="wechat-login-btn"
|
|
|
+ class="login-btn"
|
|
|
open-type="getPhoneNumber"
|
|
|
@getphonenumber="onGetPhoneNumber"
|
|
|
:loading="isLoading"
|
|
|
- hover-class="btn-hover"
|
|
|
+ hover-class="login-btn-hover"
|
|
|
>
|
|
|
- <view class="btn-shine"></view>
|
|
|
- <text class="btn-text">一键登录</text>
|
|
|
+ <text class="login-btn-text">一键登录</text>
|
|
|
</button>
|
|
|
</view>
|
|
|
|
|
|
<!-- 用户协议 -->
|
|
|
- <view class="agreement-section">
|
|
|
- <view class="agreement-card">
|
|
|
- <text class="agreement-prefix">登录即表示您已阅读并同意</text>
|
|
|
- <view class="agreement-links">
|
|
|
- <text class="link-item" @tap="goToServiceAgreement">《用户服务协议》</text>
|
|
|
- <text class="link-sep">与</text>
|
|
|
- <text class="link-item" @tap="goToPrivacyPolicy">《隐私政策》</text>
|
|
|
- </view>
|
|
|
+ <view class="agreement">
|
|
|
+ <text class="agreement-text">登录即表示您已阅读并同意</text>
|
|
|
+ <view class="agreement-links">
|
|
|
+ <text class="link" @tap="goToServiceAgreement">《用户服务协议》</text>
|
|
|
+ <text class="link-sep">与</text>
|
|
|
+ <text class="link" @tap="goToPrivacyPolicy">《隐私政策》</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 底部装饰 -->
|
|
|
- <view class="footer-decoration">
|
|
|
- <view class="dot-pattern">
|
|
|
- <view class="dot"></view>
|
|
|
- <view class="dot"></view>
|
|
|
- <view class="dot"></view>
|
|
|
- </view>
|
|
|
+ <view class="footer-dots">
|
|
|
+ <view class="dot"></view>
|
|
|
+ <view class="dot"></view>
|
|
|
+ <view class="dot"></view>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -105,10 +83,8 @@ import { logger } from '@/utils/logger';
|
|
|
|
|
|
const isLoading = ref(false);
|
|
|
|
|
|
-// 登录后跳转的页面
|
|
|
const redirectUrl = ref('');
|
|
|
|
|
|
-// 页面加载时获取redirect参数
|
|
|
onLoad((options: any) => {
|
|
|
if (options.redirect) {
|
|
|
redirectUrl.value = decodeURIComponent(options.redirect);
|
|
|
@@ -117,21 +93,20 @@ onLoad((options: any) => {
|
|
|
|
|
|
const onGetPhoneNumber = async (e: any) => {
|
|
|
logger.log('[登录] 获取手机号事件:', e.detail);
|
|
|
-
|
|
|
+
|
|
|
if (e.detail.errMsg !== 'getPhoneNumber:ok') {
|
|
|
- console.error('[登录] 获取手机号失败:', e.detail.errMsg);
|
|
|
+ logger.error('[登录] 获取手机号失败:', e.detail.errMsg);
|
|
|
uni.showToast({
|
|
|
title: '获取手机号失败,请重试',
|
|
|
icon: 'none'
|
|
|
});
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
isLoading.value = true;
|
|
|
uni.showLoading({ title: '登录中...' });
|
|
|
-
|
|
|
+
|
|
|
try {
|
|
|
- // 获取登录code
|
|
|
logger.log('[登录] 开始获取login code...');
|
|
|
const loginRes = await new Promise<any>((resolve, reject) => {
|
|
|
uni.login({
|
|
|
@@ -141,25 +116,25 @@ const onGetPhoneNumber = async (e: any) => {
|
|
|
resolve(res);
|
|
|
},
|
|
|
fail: (err) => {
|
|
|
- console.error('[登录] login失败:', err);
|
|
|
+ logger.error('[登录] login失败:', err);
|
|
|
reject(err);
|
|
|
}
|
|
|
});
|
|
|
});
|
|
|
-
|
|
|
+
|
|
|
logger.log('[登录] loginRes:', loginRes);
|
|
|
logger.log('[登录] phoneCode:', e.detail.code);
|
|
|
-
|
|
|
+
|
|
|
const { code, encryptedData, iv } = e.detail;
|
|
|
- const res = await loginByMiniappPhone({
|
|
|
+ const res = await loginByMiniappPhone({
|
|
|
code: loginRes.code,
|
|
|
phoneCode: code
|
|
|
});
|
|
|
logger.log('[登录] 登录成功:', res);
|
|
|
handleLoginSuccess(res);
|
|
|
} catch (error: any) {
|
|
|
- console.error('[登录] 微信手机号登录失败', error);
|
|
|
- console.error('[登录] 错误详情:', error.message || error);
|
|
|
+ logger.error('[登录] 微信手机号登录失败', error);
|
|
|
+ logger.error('[登录] 错误详情:', error.message || error);
|
|
|
uni.showToast({
|
|
|
title: error.message || '登录失败,请重试',
|
|
|
icon: 'none',
|
|
|
@@ -183,7 +158,7 @@ const handleLoginSuccess = (res: LoginResult) => {
|
|
|
logger.log('[登录成功] 保存后验证 - token:', savedToken ? '已保存' : '保存失败');
|
|
|
|
|
|
uni.vibrateShort({ type: 'medium' });
|
|
|
-
|
|
|
+
|
|
|
uni.showToast({
|
|
|
title: '登录成功',
|
|
|
icon: 'success'
|
|
|
@@ -203,14 +178,12 @@ const handleLoginSuccess = (res: LoginResult) => {
|
|
|
}, 1000);
|
|
|
};
|
|
|
|
|
|
-// 跳转到用户服务协议
|
|
|
const goToServiceAgreement = () => {
|
|
|
uni.navigateTo({
|
|
|
url: '/pages/agreement/serviceAgreement'
|
|
|
});
|
|
|
};
|
|
|
|
|
|
-// 跳转到隐私政策
|
|
|
const goToPrivacyPolicy = () => {
|
|
|
uni.navigateTo({
|
|
|
url: '/pages/agreement/privacyPolicy'
|
|
|
@@ -221,12 +194,12 @@ const goToPrivacyPolicy = () => {
|
|
|
<style lang="scss">
|
|
|
.container {
|
|
|
min-height: 100vh;
|
|
|
- background: linear-gradient(180deg, #FFFBF0 0%, #FFF9E6 30%, #FFFFFF 70%);
|
|
|
+ background: linear-gradient(180deg, $color-primary-bg 0%, #FFF9E6 30%, $color-bg-secondary 100%);
|
|
|
position: relative;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
|
|
|
-/* ========== 动态背景层 ========== */
|
|
|
+/* ========== 背景层 ========== */
|
|
|
.bg-layer {
|
|
|
position: fixed;
|
|
|
top: 0;
|
|
|
@@ -235,66 +208,17 @@ const goToPrivacyPolicy = () => {
|
|
|
bottom: 0;
|
|
|
z-index: 0;
|
|
|
pointer-events: none;
|
|
|
- contain: layout style paint;
|
|
|
}
|
|
|
|
|
|
.gradient-orb {
|
|
|
position: absolute;
|
|
|
+ width: 500rpx;
|
|
|
+ height: 500rpx;
|
|
|
border-radius: 50%;
|
|
|
- will-change: transform, opacity;
|
|
|
- transform: translateZ(0);
|
|
|
- backface-visibility: hidden;
|
|
|
-
|
|
|
- &.orb-1 {
|
|
|
- width: 500rpx;
|
|
|
- height: 500rpx;
|
|
|
- background: radial-gradient(circle, rgba(255, 215, 0, 0.2) 0%, transparent 70%);
|
|
|
- top: -150rpx;
|
|
|
- right: -100rpx;
|
|
|
- animation: float 8s ease-in-out infinite;
|
|
|
- }
|
|
|
-
|
|
|
- &.orb-2 {
|
|
|
- width: 400rpx;
|
|
|
- height: 400rpx;
|
|
|
- background: radial-gradient(circle, rgba(255, 193, 7, 0.15) 0%, transparent 70%);
|
|
|
- top: 200rpx;
|
|
|
- left: -120rpx;
|
|
|
- animation: float 10s ease-in-out infinite reverse;
|
|
|
- }
|
|
|
-
|
|
|
- &.orb-3 {
|
|
|
- width: 350rpx;
|
|
|
- height: 350rpx;
|
|
|
- background: radial-gradient(circle, rgba(255, 235, 59, 0.12) 0%, transparent 70%);
|
|
|
- bottom: 200rpx;
|
|
|
- right: -80rpx;
|
|
|
- animation: float 12s ease-in-out infinite 2s;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.wave-container {
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- height: 400rpx;
|
|
|
- overflow: hidden;
|
|
|
-}
|
|
|
-
|
|
|
-.wave {
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: -50%;
|
|
|
- width: 200%;
|
|
|
- height: 400rpx;
|
|
|
- background: linear-gradient(180deg, transparent 0%, rgba(255, 215, 0, 0.05) 100%);
|
|
|
- border-radius: 45% 48% 43% 47%;
|
|
|
- animation: wave 15s linear infinite;
|
|
|
-
|
|
|
- &.wave-2 {
|
|
|
- display: none; /* 移除第二道波浪以提升性能 */
|
|
|
- }
|
|
|
+ background: radial-gradient(circle, rgba(255, 215, 0, 0.15) 0%, transparent 70%);
|
|
|
+ top: -120rpx;
|
|
|
+ right: -80rpx;
|
|
|
+ animation: orb-float 8s ease-in-out infinite;
|
|
|
}
|
|
|
|
|
|
/* ========== 主内容区 ========== */
|
|
|
@@ -303,9 +227,10 @@ const goToPrivacyPolicy = () => {
|
|
|
z-index: 1;
|
|
|
display: flex;
|
|
|
flex-direction: column;
|
|
|
- padding: 0 40rpx;
|
|
|
- padding-bottom: calc(160rpx + constant(safe-area-inset-bottom));
|
|
|
- padding-bottom: calc(160rpx + env(safe-area-inset-bottom));
|
|
|
+ align-items: center;
|
|
|
+ padding: 0 48rpx;
|
|
|
+ padding-bottom: calc(80rpx + constant(safe-area-inset-bottom));
|
|
|
+ padding-bottom: calc(80rpx + env(safe-area-inset-bottom));
|
|
|
}
|
|
|
|
|
|
/* ========== 品牌展示区 ========== */
|
|
|
@@ -314,113 +239,78 @@ const goToPrivacyPolicy = () => {
|
|
|
flex-direction: column;
|
|
|
align-items: center;
|
|
|
padding-top: 160rpx;
|
|
|
- padding-bottom: 80rpx;
|
|
|
- animation: slideDown 0.3s ease;
|
|
|
+ padding-bottom: 72rpx;
|
|
|
+ animation: slide-down 0.35s $ease-out;
|
|
|
}
|
|
|
|
|
|
.logo-wrapper {
|
|
|
- margin-bottom: 56rpx;
|
|
|
- will-change: transform;
|
|
|
- transform: translateZ(0);
|
|
|
+ margin-bottom: 48rpx;
|
|
|
|
|
|
- .logo-outer-ring {
|
|
|
- width: 280rpx;
|
|
|
- height: 280rpx;
|
|
|
+ .logo-ring {
|
|
|
+ width: 220rpx;
|
|
|
+ height: 220rpx;
|
|
|
border-radius: 50%;
|
|
|
- border: 2rpx solid rgba(255, 215, 0, 0.25);
|
|
|
+ border: 2rpx solid rgba(255, 193, 7, 0.2);
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- animation: ringRotate 20s linear infinite;
|
|
|
+ position: relative;
|
|
|
+ animation: ring-rotate 30s linear infinite;
|
|
|
+
|
|
|
+ .logo-glow {
|
|
|
+ position: absolute;
|
|
|
+ width: 200rpx;
|
|
|
+ height: 200rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: radial-gradient(circle, rgba(255, 193, 7, 0.12) 0%, transparent 70%);
|
|
|
+ animation: glow-pulse 3s ease-in-out infinite;
|
|
|
+ }
|
|
|
|
|
|
- .logo-inner-ring {
|
|
|
- width: 256rpx;
|
|
|
- height: 256rpx;
|
|
|
+ .logo-circle {
|
|
|
+ width: 170rpx;
|
|
|
+ height: 170rpx;
|
|
|
+ background: $color-bg-primary;
|
|
|
border-radius: 50%;
|
|
|
- border: 2rpx dashed rgba(255, 215, 0, 0.3);
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
+ box-shadow: $shadow-md, inset 0 2rpx 8rpx rgba(255, 255, 255, 0.6);
|
|
|
+ padding: 32rpx;
|
|
|
position: relative;
|
|
|
+ z-index: 1;
|
|
|
|
|
|
- .logo-glow {
|
|
|
- position: absolute;
|
|
|
- width: 240rpx;
|
|
|
- height: 240rpx;
|
|
|
- border-radius: 50%;
|
|
|
- background: radial-gradient(circle, rgba(255, 215, 0, 0.15) 0%, transparent 70%);
|
|
|
- /* 移除filter: blur()以提升性能 */
|
|
|
- opacity: 0.8;
|
|
|
- animation: pulse 4s ease-in-out infinite;
|
|
|
- }
|
|
|
-
|
|
|
- .logo-circle {
|
|
|
- width: 220rpx;
|
|
|
- height: 220rpx;
|
|
|
- background: linear-gradient(135deg, #FFFFFF 0%, #FFFEF5 100%);
|
|
|
- border-radius: 50%;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- box-shadow:
|
|
|
- 0 16rpx 40rpx rgba(255, 193, 7, 0.2),
|
|
|
- inset 0 2rpx 8rpx rgba(255, 255, 255, 0.6);
|
|
|
- padding: 28rpx;
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
-
|
|
|
- .logo {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- /* 移除drop-shadow滤镜 */
|
|
|
- }
|
|
|
+ .logo {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.brand-text-group {
|
|
|
- text-align: center;
|
|
|
- margin-bottom: 48rpx;
|
|
|
-
|
|
|
- .brand-title {
|
|
|
- font-size: 56rpx;
|
|
|
- font-weight: 700;
|
|
|
- background: linear-gradient(135deg, #333333 0%, #666666 100%);
|
|
|
- -webkit-background-clip: text;
|
|
|
- -webkit-text-fill-color: transparent;
|
|
|
- background-clip: text;
|
|
|
- letter-spacing: 4rpx;
|
|
|
- display: block;
|
|
|
- margin-bottom: 16rpx;
|
|
|
- }
|
|
|
-
|
|
|
- .brand-subtitle {
|
|
|
- font-size: 26rpx;
|
|
|
- color: #888888;
|
|
|
- letter-spacing: 2rpx;
|
|
|
- font-weight: 400;
|
|
|
- }
|
|
|
+.brand-name {
|
|
|
+ font-size: 48rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ color: $color-text-primary;
|
|
|
+ letter-spacing: 6rpx;
|
|
|
+ margin-bottom: 12rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.brand-desc {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: $color-text-secondary;
|
|
|
+ letter-spacing: 2rpx;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
}
|
|
|
|
|
|
.feature-tags {
|
|
|
display: flex;
|
|
|
gap: 20rpx;
|
|
|
- justify-content: center;
|
|
|
|
|
|
.tag {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 8rpx;
|
|
|
- padding: 12rpx 20rpx;
|
|
|
+ padding: 12rpx 24rpx;
|
|
|
background: rgba(255, 255, 255, 0.9);
|
|
|
border-radius: 40rpx;
|
|
|
- box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.06);
|
|
|
- border: 1rpx solid rgba(255, 215, 0, 0.2);
|
|
|
-
|
|
|
- .tag-icon {
|
|
|
- font-size: 24rpx;
|
|
|
- }
|
|
|
+ box-shadow: $shadow-sm;
|
|
|
|
|
|
.tag-text {
|
|
|
font-size: 22rpx;
|
|
|
@@ -432,238 +322,157 @@ const goToPrivacyPolicy = () => {
|
|
|
|
|
|
/* ========== 登录卡片 ========== */
|
|
|
.login-card {
|
|
|
- background: rgba(255, 255, 255, 0.98);
|
|
|
- border-radius: 32rpx;
|
|
|
- padding: 56rpx 40rpx;
|
|
|
- margin-bottom: 40rpx;
|
|
|
- box-shadow:
|
|
|
- 0 16rpx 48rpx rgba(0, 0, 0, 0.06),
|
|
|
- inset 0 1rpx 0 rgba(255, 255, 255, 0.8);
|
|
|
- border: 1rpx solid rgba(255, 215, 0, 0.15);
|
|
|
- animation: slideUp 0.3s ease 0.1s both;
|
|
|
- will-change: transform, opacity;
|
|
|
- transform: translateZ(0);
|
|
|
+ width: 100%;
|
|
|
+ background: $color-bg-primary;
|
|
|
+ border-radius: $radius-xl;
|
|
|
+ padding: 48rpx 40rpx 40rpx;
|
|
|
+ box-shadow: $shadow-lg;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ box-sizing: border-box;
|
|
|
+ animation: slide-up 0.35s $ease-out 0.1s both;
|
|
|
}
|
|
|
|
|
|
.card-header {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- gap: 24rpx;
|
|
|
- margin-bottom: 60rpx;
|
|
|
-
|
|
|
+ gap: 20rpx;
|
|
|
+ margin-bottom: 48rpx;
|
|
|
+
|
|
|
.header-line {
|
|
|
- width: 80rpx;
|
|
|
+ width: 64rpx;
|
|
|
height: 2rpx;
|
|
|
- background: linear-gradient(90deg, transparent 0%, rgba(255, 215, 0, 0.4) 100%);
|
|
|
-
|
|
|
+ background: linear-gradient(90deg, transparent, $color-primary-light);
|
|
|
+
|
|
|
&:last-child {
|
|
|
- background: linear-gradient(90deg, rgba(255, 215, 0, 0.4) 0%, transparent 100%);
|
|
|
+ background: linear-gradient(90deg, $color-primary-light, transparent);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
.card-title {
|
|
|
- font-size: 30rpx;
|
|
|
+ font-size: 28rpx;
|
|
|
font-weight: 600;
|
|
|
- color: #333333;
|
|
|
+ color: $color-text-primary;
|
|
|
letter-spacing: 2rpx;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-.wechat-login-btn {
|
|
|
+.login-btn {
|
|
|
width: 100%;
|
|
|
- min-height: 108rpx;
|
|
|
- background: linear-gradient(135deg, #FFD700 0%, #FFC107 50%, #FFB300 100%);
|
|
|
+ height: 108rpx;
|
|
|
+ background: linear-gradient(135deg, #FFD700, $color-primary, $color-primary-dark);
|
|
|
border-radius: 54rpx;
|
|
|
border: none;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
justify-content: center;
|
|
|
- position: relative;
|
|
|
- overflow: hidden;
|
|
|
- box-shadow:
|
|
|
- 0 12rpx 40rpx rgba(255, 193, 7, 0.35),
|
|
|
- 0 4rpx 16rpx rgba(255, 193, 7, 0.2),
|
|
|
- inset 0 2rpx 0 rgba(255, 255, 255, 0.3);
|
|
|
- transition: all 0.3s cubic-bezier(0.25, 0.1, 0.25, 1);
|
|
|
+ box-shadow: $shadow-primary, 0 4rpx 16rpx rgba(255, 193, 7, 0.2);
|
|
|
|
|
|
&::after {
|
|
|
border: none;
|
|
|
}
|
|
|
|
|
|
- .btn-shine {
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: -100%;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- background: linear-gradient(
|
|
|
- 90deg,
|
|
|
- transparent 0%,
|
|
|
- rgba(255, 255, 255, 0.3) 50%,
|
|
|
- transparent 100%
|
|
|
- );
|
|
|
- transition: left 0.6s ease;
|
|
|
- }
|
|
|
-
|
|
|
- &.btn-hover {
|
|
|
- transform: translateY(-4rpx) scale(1.02);
|
|
|
- box-shadow:
|
|
|
- 0 16rpx 48rpx rgba(255, 193, 7, 0.45),
|
|
|
- 0 6rpx 20rpx rgba(255, 193, 7, 0.25),
|
|
|
- inset 0 2rpx 0 rgba(255, 255, 255, 0.4);
|
|
|
-
|
|
|
- .btn-shine {
|
|
|
- left: 100%;
|
|
|
- }
|
|
|
+ &:active {
|
|
|
+ transform: scale(0.98);
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- .btn-text {
|
|
|
- font-size: 36rpx;
|
|
|
- font-weight: 600;
|
|
|
- color: #1A1A1A;
|
|
|
- letter-spacing: 8rpx;
|
|
|
- position: relative;
|
|
|
- z-index: 1;
|
|
|
- white-space: nowrap;
|
|
|
- }
|
|
|
+.login-btn-hover {
|
|
|
+ transform: translateY(-2rpx) scale(1.01);
|
|
|
+ box-shadow: 0 12rpx 36rpx rgba(255, 193, 7, 0.4), 0 6rpx 20rpx rgba(255, 193, 7, 0.25);
|
|
|
}
|
|
|
|
|
|
-/* ========== 用户协议 ========== */
|
|
|
-.agreement-section {
|
|
|
- animation: fadeIn 0.35s ease 0.15s both;
|
|
|
+.login-btn-text {
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #1A1A1A;
|
|
|
+ letter-spacing: 4rpx;
|
|
|
}
|
|
|
|
|
|
-.agreement-card {
|
|
|
+/* ========== 用户协议 ========== */
|
|
|
+.agreement {
|
|
|
text-align: center;
|
|
|
- padding: 28rpx 36rpx;
|
|
|
- background: rgba(255, 255, 255, 0.85);
|
|
|
- border-radius: 20rpx;
|
|
|
- border: 1rpx solid rgba(0, 0, 0, 0.04);
|
|
|
-
|
|
|
- .agreement-prefix {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #AAAAAA;
|
|
|
- display: block;
|
|
|
- margin-bottom: 8rpx;
|
|
|
- }
|
|
|
+ padding: 40rpx 32rpx 0;
|
|
|
+ animation: fade-in 0.4s $ease-out 0.2s both;
|
|
|
+}
|
|
|
|
|
|
- .agreement-links {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- gap: 8rpx;
|
|
|
- flex-wrap: wrap;
|
|
|
-
|
|
|
- .link-item {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #FFB300;
|
|
|
- font-weight: 600;
|
|
|
- text-decoration: underline;
|
|
|
- text-decoration-color: rgba(255, 179, 0, 0.3);
|
|
|
- cursor: pointer;
|
|
|
-
|
|
|
- &:active {
|
|
|
- opacity: 0.6;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .link-sep {
|
|
|
- font-size: 24rpx;
|
|
|
- color: #CCCCCC;
|
|
|
- }
|
|
|
- }
|
|
|
+.agreement-text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: $color-text-tertiary;
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
}
|
|
|
|
|
|
-/* ========== 底部装饰 ========== */
|
|
|
-.footer-decoration {
|
|
|
+.agreement-links {
|
|
|
display: flex;
|
|
|
+ align-items: center;
|
|
|
justify-content: center;
|
|
|
- margin-top: auto;
|
|
|
- padding-top: 60rpx;
|
|
|
+ gap: 4rpx;
|
|
|
+ flex-wrap: wrap;
|
|
|
+}
|
|
|
|
|
|
- .dot-pattern {
|
|
|
- display: flex;
|
|
|
- gap: 12rpx;
|
|
|
+.link {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: $color-primary-dark;
|
|
|
+ font-weight: 500;
|
|
|
|
|
|
- .dot {
|
|
|
- width: 12rpx;
|
|
|
- height: 12rpx;
|
|
|
- border-radius: 50%;
|
|
|
- background: linear-gradient(135deg, #FFD700 0%, #FFC107 100%);
|
|
|
- opacity: 0.4;
|
|
|
- /* 移除脉冲动画以提升性能 */
|
|
|
- }
|
|
|
+ &:active {
|
|
|
+ opacity: 0.6;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* ========== 动画关键帧 ========== */
|
|
|
-@keyframes float {
|
|
|
- 0%, 100% {
|
|
|
- transform: translateY(0) scale(1);
|
|
|
- }
|
|
|
- 50% {
|
|
|
- transform: translateY(-30rpx) scale(1.05);
|
|
|
- }
|
|
|
+.link-sep {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: $color-text-tertiary;
|
|
|
}
|
|
|
|
|
|
-@keyframes wave {
|
|
|
- 0% {
|
|
|
- transform: translateX(0) rotate(0deg);
|
|
|
- }
|
|
|
- 100% {
|
|
|
- transform: translateX(50%) rotate(360deg);
|
|
|
+/* ========== 底部装饰 ========== */
|
|
|
+.footer-dots {
|
|
|
+ display: flex;
|
|
|
+ gap: 12rpx;
|
|
|
+ justify-content: center;
|
|
|
+ margin-top: auto;
|
|
|
+ padding-top: 64rpx;
|
|
|
+
|
|
|
+ .dot {
|
|
|
+ width: 10rpx;
|
|
|
+ height: 10rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: $color-primary-light;
|
|
|
+ opacity: 0.5;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-@keyframes slideDown {
|
|
|
- from {
|
|
|
- opacity: 0;
|
|
|
- transform: translateY(-60rpx);
|
|
|
- }
|
|
|
- to {
|
|
|
- opacity: 1;
|
|
|
- transform: translateY(0);
|
|
|
- }
|
|
|
+/* ========== 动画 ========== */
|
|
|
+@keyframes orb-float {
|
|
|
+ 0%, 100% { transform: translateY(0) scale(1); }
|
|
|
+ 50% { transform: translateY(-24rpx) scale(1.04); }
|
|
|
}
|
|
|
|
|
|
-@keyframes slideUp {
|
|
|
- from {
|
|
|
- opacity: 0;
|
|
|
- transform: translateY(60rpx);
|
|
|
- }
|
|
|
- to {
|
|
|
- opacity: 1;
|
|
|
- transform: translateY(0);
|
|
|
- }
|
|
|
+@keyframes ring-rotate {
|
|
|
+ from { transform: rotate(0deg); }
|
|
|
+ to { transform: rotate(360deg); }
|
|
|
}
|
|
|
|
|
|
-@keyframes fadeIn {
|
|
|
- from {
|
|
|
- opacity: 0;
|
|
|
- }
|
|
|
- to {
|
|
|
- opacity: 1;
|
|
|
- }
|
|
|
+@keyframes glow-pulse {
|
|
|
+ 0%, 100% { opacity: 0.6; transform: scale(1); }
|
|
|
+ 50% { opacity: 1; transform: scale(1.08); }
|
|
|
}
|
|
|
|
|
|
-@keyframes pulse {
|
|
|
- 0%, 100% {
|
|
|
- opacity: 0.25;
|
|
|
- transform: scale(1);
|
|
|
- }
|
|
|
- 50% {
|
|
|
- opacity: 0.4;
|
|
|
- transform: scale(1.05);
|
|
|
- }
|
|
|
+@keyframes slide-down {
|
|
|
+ from { opacity: 0; transform: translateY(-40rpx); }
|
|
|
+ to { opacity: 1; transform: translateY(0); }
|
|
|
}
|
|
|
|
|
|
-@keyframes ringRotate {
|
|
|
- from {
|
|
|
- transform: rotate(0deg);
|
|
|
- }
|
|
|
- to {
|
|
|
- transform: rotate(360deg);
|
|
|
- }
|
|
|
+@keyframes slide-up {
|
|
|
+ from { opacity: 0; transform: translateY(40rpx); }
|
|
|
+ to { opacity: 1; transform: translateY(0); }
|
|
|
+}
|
|
|
+
|
|
|
+@keyframes fade-in {
|
|
|
+ from { opacity: 0; }
|
|
|
+ to { opacity: 1; }
|
|
|
}
|
|
|
</style>
|