1046 lines
25 KiB
Plaintext
1046 lines
25 KiB
Plaintext
<template>
|
|
<view class="page">
|
|
<!-- 顶部装饰 -->
|
|
<view class="top-deco">
|
|
<view class="deco-circle circle-1"></view>
|
|
<view class="deco-circle circle-2"></view>
|
|
<view class="deco-circle circle-3"></view>
|
|
</view>
|
|
<!-- 应用Logo和标题 -->
|
|
<view class="app-header">
|
|
<image class="app-logo" src="/static/logo.png" mode="aspectFit"></image>
|
|
<text class="app-name">缘友</text>
|
|
<text class="app-slogan">遇见美好,遇见你</text>
|
|
</view>
|
|
<!-- 登录方式切换 -->
|
|
<view class="tabsbox" style="justify-content: space-around;padding: 20rpx 48rpx;">
|
|
<view v-for="(tab, index) in loginTabs" :key="index" class="tabsbox-item" style="flex: 1; padding: 20rpx;"
|
|
:class="{ 'tabsbox-active': activeTab === index }" @click="switchTab(index)">
|
|
<text class="tabsbox-text" :class="{ 'tabsbox-active-txt': activeTab === index }">{{ tab }}</text>
|
|
</view>
|
|
</view>
|
|
<!-- 手机号登录表单 -->
|
|
<view v-if="activeTab == 2" class="login-form">
|
|
<!-- 手机号输入 -->
|
|
<view class="form-group">
|
|
<view class="input-with-icon">
|
|
<uni-icons type="phone" size="20" color="#999"></uni-icons>
|
|
<view class="input-wrapper">
|
|
<view class="area-code" @click="showAreaCodePicker">
|
|
<text class="area-code-text">+{{ areaCode }}</text>
|
|
<uni-icons type="arrowdown" size="12" color="#666"></uni-icons>
|
|
</view>
|
|
<input v-model="phoneNumber" class="form-input" type="number" placeholder="请输入手机号码"
|
|
:maxlength="11" @input="onPhoneInput" />
|
|
</view>
|
|
</view>
|
|
<text v-if="phoneError" class="error-msg">{{ phoneError }}</text>
|
|
</view>
|
|
<!-- 密码输入 -->
|
|
<view class="form-group">
|
|
<view class="input-with-icon">
|
|
<uni-icons type="locked" size="20" color="#999"></uni-icons>
|
|
<input v-model="password" class="form-input" :type="showPassword ? 'text' : 'password'"
|
|
placeholder="请输入密码" @input="onPasswordInput" />
|
|
<view class="eye-icon" @click="togglePassword">
|
|
<uni-icons :type="showPassword ? 'eye' : 'eye-slash'" size="20" color="#999"></uni-icons>
|
|
</view>
|
|
</view>
|
|
<text v-if="passwordError" class="error-msg">{{ passwordError }}</text>
|
|
</view>
|
|
|
|
<!-- 记住密码和忘记密码 -->
|
|
<view class="form-options">
|
|
<view class="remember-me" @click="toggleRemember">
|
|
<view class="checkbox" :class="{ checked: rememberMe }">
|
|
<uni-icons v-if="rememberMe" type="checkmark" size="12" color="#fff"></uni-icons>
|
|
</view>
|
|
<text class="option-text">记住密码</text>
|
|
</view>
|
|
<view class="forgot-password" @click="forgotPassword">
|
|
<text class="forgot-text">忘记密码?</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 登录按钮 -->
|
|
<button class="login-btn" :class="{ disabled: !canLogin }" :disabled="!canLogin" @click="onLogin">
|
|
<text v-if="!loading" style="text-align: center;">登录</text>
|
|
<view v-else class="loading">
|
|
<uni-icons type="spinner-cycle" size="20" color="#fff"></uni-icons>
|
|
<text style="text-align: center;">登录中...</text>
|
|
</view>
|
|
</button>
|
|
</view>
|
|
|
|
<!-- 验证码登录表单 -->
|
|
<view v-if="activeTab == 0" class="login-form">
|
|
<!-- 手机号输入 -->
|
|
<view class="form-group">
|
|
<view class="input-with-icon">
|
|
<uni-icons type="phone" size="20" color="#999"></uni-icons>
|
|
<view class="input-wrapper">
|
|
<view class="area-code" @click="showAreaCodePicker">
|
|
<text class="area-code-text">+{{ areaCode }}</text>
|
|
<uni-icons type="arrowdown" size="12" color="#666"></uni-icons>
|
|
</view>
|
|
<input v-model="phoneNumber" class="form-input" type="number" placeholder="请输入手机号码"
|
|
:maxlength="11" @input="onPhoneInput" />
|
|
</view>
|
|
</view>
|
|
<text v-if="phoneError" class="error-msg">{{ phoneError }}</text>
|
|
</view>
|
|
|
|
<!-- 验证码输入 -->
|
|
<view class="form-group">
|
|
<view class="input-with-icon">
|
|
<uni-icons type="mail" size="20" color="#999"></uni-icons>
|
|
<input v-model="smsCode" class="form-input" type="number" placeholder="请输入验证码" :maxlength="6"
|
|
@input="onSmsCodeInput" />
|
|
<button class="sms-btn" :disabled="!canSendSms" @click="sendSmsCode"> {{ smsBtnText }} </button>
|
|
</view>
|
|
<text v-if="smsCodeError" class="error-msg">{{ smsCodeError }}</text>
|
|
</view>
|
|
|
|
<!-- 登录按钮 -->
|
|
<button class="login-btn" :class="{ disabled: !canSmsLogin }" :disabled="!canSmsLogin" @click="onSmsLogin">
|
|
<text class="login-btn-txt" v-if="!loading" style="text-align: center;">登录</text>
|
|
<view v-else class="loading">
|
|
<uni-icons type="spinner-cycle" size="20" color="#fff"></uni-icons>
|
|
<text class="login-btn-txt">登录中...</text>
|
|
</view>
|
|
</button>
|
|
</view>
|
|
|
|
<!-- 一键登录(手机号快速验证) -->
|
|
<view v-if="activeTab ==1" class="quick-login">
|
|
<view class="quick-login-tip">
|
|
<text>本机号码一键登录</text>
|
|
<text class="tip-sub">快速安全,免输密码</text>
|
|
</view>
|
|
|
|
<button class="quick-login-btn" @click="onQuickLogin">
|
|
<view class="quick-login-content">
|
|
<uni-icons type="phone" size="24" color="#fff"></uni-icons>
|
|
<text>本机号码一键登录</text>
|
|
</view>
|
|
</button>
|
|
|
|
<view class="agreement">
|
|
<text class="agreement-text">点击登录即表示同意</text>
|
|
<text class="agreement-link" @click="showAgreement">《用户协议》</text>
|
|
<text class="agreement-link" @click="showPrivacy">《隐私政策》</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 第三方登录
|
|
<view class="third-party-login">
|
|
<view class="divider">
|
|
<view class="divider-line"></view>
|
|
<text class="divider-text">其他登录方式</text>
|
|
<view class="divider-line"></view>
|
|
</view>
|
|
|
|
<view class="third-party-buttons">
|
|
<view class="third-party-btn wechat" @click="onWechatLogin">
|
|
<uni-icons type="weixin" size="28" color="#fff"></uni-icons>
|
|
<text class="btn-text">微信</text>
|
|
</view>
|
|
<view class="third-party-btn qq" @click="onQQLogin">
|
|
<uni-icons type="qq" size="28" color="#fff"></uni-icons>
|
|
<text class="btn-text">QQ</text>
|
|
</view>
|
|
<view class="third-party-btn apple" @click="onAppleLogin">
|
|
<uni-icons type="apple" size="28" color="#fff"></uni-icons>
|
|
<text class="btn-text">Apple</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
-->
|
|
|
|
<!-- 注册入口 -->
|
|
<view class="register-link">
|
|
<text class="register-link-text">还没有账号?</text>
|
|
<text class="register-text" @click="goRegister">立即注册</text>
|
|
</view>
|
|
|
|
<!-- 协议弹窗 -->
|
|
<view v-if="showAgreementModal" class="agreement-modal" @click="closeAgreementModal">
|
|
<view class="modal-content" @click.stop>
|
|
<view class="modal-header">
|
|
<text class="modal-title">用户协议</text>
|
|
<uni-icons type="close" size="20" color="#999" @click="closeAgreementModal"></uni-icons>
|
|
</view>
|
|
<scroll-view class="modal-body" scroll-y>
|
|
<text class="agreement-content">
|
|
【用户协议】
|
|
|
|
欢迎使用心遇社交应用!在开始使用前,请仔细阅读以下用户协议:
|
|
|
|
1. 服务条款
|
|
本应用提供社交交友服务,包括但不限于用户匹配、聊天互动、动态分享等功能。
|
|
|
|
2. 用户行为规范
|
|
- 禁止发布违法、违规信息
|
|
- 禁止骚扰、侮辱其他用户
|
|
- 禁止传播虚假信息
|
|
- 保护他人隐私,禁止泄露他人信息
|
|
|
|
3. 隐私保护
|
|
我们高度重视用户隐私保护,详细政策请查看《隐私政策》。
|
|
|
|
4. 免责声明
|
|
因用户行为产生的纠纷,本应用不承担法律责任。
|
|
|
|
5. 协议修改
|
|
本协议可能会进行修改,修改后将通过应用内通知告知用户。
|
|
|
|
继续使用即表示您同意以上协议。
|
|
</text>
|
|
</scroll-view>
|
|
<view class="modal-footer">
|
|
<button class="modal-btn" @click="closeAgreementModal">同意并继续</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 区号选择弹窗 -->
|
|
<view v-if="showAreaCodeModal" class="area-code-modal" @click="closeAreaCodePicker">
|
|
<view class="modal-content" @click.stop>
|
|
<view class="modal-header">
|
|
<text class="modal-title">选择国家/地区</text>
|
|
<uni-icons type="close" size="20" color="#999" @click="closeAreaCodePicker"></uni-icons>
|
|
</view>
|
|
<scroll-view class="modal-body" scroll-y>
|
|
<view v-for="(item, index) in areaCodeList" :key="index" class="area-code-item"
|
|
:class="{ active: item.code === areaCode, 'area-code-item-last': index === areaCodeList.length - 1 }"
|
|
@click="selectAreaCode(item)">
|
|
<text class="country-name">{{ item.country }}</text>
|
|
<text class="country-code">+{{ item.code }}</text>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup lang="uts">
|
|
import { isLoggedIn } from "@/stores/user.uts"
|
|
import { IUserInfo } from "@/types/user.uts"
|
|
import { Api } from "@/common/api-service.uts"
|
|
|
|
const activeTab = ref(0) // 0:密码登录, 1:验证码登录, 2:一键登录
|
|
const phoneNumber = ref('18620175727')
|
|
const password = ref('')
|
|
const smsCode = ref('729154')
|
|
const showPassword = ref(false)
|
|
const rememberMe = ref(true)
|
|
const loading = ref(false)
|
|
const phoneError = ref<string | null>(null)
|
|
const passwordError = ref<string | null>(null)
|
|
const smsCodeError = ref<string | null>(null)
|
|
const smsBtnText = ref('获取验证码')
|
|
const countdown = ref(0)
|
|
const countdownTimer = ref<number | null>(null)
|
|
const areaCode = ref('86')
|
|
const showAgreementModal = ref(false)
|
|
const showAreaCodeModal = ref(false)
|
|
|
|
// 登录标签
|
|
const loginTabs = ref(['验证码登录', '一键登录'])
|
|
|
|
type IAreaCodeItem = {
|
|
country : string
|
|
code : string
|
|
}
|
|
// 区号列表
|
|
const areaCodeList = reactive<IAreaCodeItem[]>([
|
|
{ country: '中国大陆', code: '86' },
|
|
{ country: '中国香港', code: '852' },
|
|
{ country: '中国澳门', code: '853' },
|
|
{ country: '中国台湾', code: '886' },
|
|
{ country: '美国', code: '1' },
|
|
{ country: '日本', code: '81' },
|
|
{ country: '韩国', code: '82' },
|
|
{ country: '新加坡', code: '65' },
|
|
{ country: '马来西亚', code: '60' },
|
|
{ country: '英国', code: '44' },
|
|
{ country: '澳大利亚', code: '61' }
|
|
] as IAreaCodeItem[])
|
|
|
|
const canLogin = computed(() => {
|
|
return phoneNumber.value.length == 11 && password.value.length >= 6 //&& phoneError.value == null && passwordError.value == null
|
|
})
|
|
|
|
const canSendSms = computed(() => {
|
|
return phoneNumber.value.length == 11 && countdown.value == 0 //&& phoneError.value == null && smsCodeError.value == null
|
|
})
|
|
|
|
const canSmsLogin = computed(() => {
|
|
return phoneNumber.value.length == 11 && smsCode.value.length == 6 //&& phoneError.value == null && smsCodeError.value == null
|
|
})
|
|
// 加载保存的登录凭证
|
|
const loadSavedCredentials = () => {
|
|
// try {
|
|
// const savedPhone = uni.getStorageSync('rememberedPhone')
|
|
// const savedPassword = uni.getStorageSync('rememberedPassword')
|
|
|
|
// if (savedPhone != null && savedPassword != null) {
|
|
// phoneNumber.value = savedPhone as string
|
|
// password.value = savedPassword as string
|
|
// rememberMe.value = true
|
|
// console.log('登录凭证已加载')
|
|
// }
|
|
// } catch (e) {
|
|
// console.error('加载登录凭证失败:', e)
|
|
// }
|
|
}
|
|
// 页面加载
|
|
onMounted(() => {
|
|
console.log('登录页面加载完成')
|
|
// 尝试加载保存的用户名和密码
|
|
console.log("isLoggedIn>>", isLoggedIn.value)
|
|
|
|
loadSavedCredentials()
|
|
})
|
|
|
|
// 切换登录方式
|
|
const switchTab = (index : number) => {
|
|
activeTab.value = index
|
|
console.log('切换到登录方式:', loginTabs.value[index])
|
|
// 清除错误信息
|
|
phoneError.value = ''
|
|
passwordError.value = ''
|
|
smsCodeError.value = ''
|
|
}
|
|
|
|
// 手机号输入验证
|
|
const onPhoneInput = () => {
|
|
if (phoneNumber.value.length == 0) {
|
|
phoneError.value = '手机号不能为空'
|
|
} else if (phoneNumber.value.length != 11) {
|
|
phoneError.value = '手机号格式不正确'
|
|
} else if (!/^1[3-9]\d{9}$/.test(phoneNumber.value)) {
|
|
phoneError.value = '请输入有效的手机号'
|
|
} else {
|
|
phoneError.value = ''
|
|
}
|
|
}
|
|
|
|
// 密码输入验证
|
|
const onPasswordInput = () => {
|
|
if (password.value.length == 0) {
|
|
passwordError.value = '密码不能为空'
|
|
} else if (password.value.length < 6) {
|
|
passwordError.value = '密码长度不能少于6位'
|
|
} else {
|
|
passwordError.value = ''
|
|
}
|
|
}
|
|
|
|
// 验证码输入验证
|
|
const onSmsCodeInput = () => {
|
|
if (smsCode.value.length == 0) {
|
|
smsCodeError.value = '验证码不能为空'
|
|
} else if (smsCode.value.length != 6) {
|
|
smsCodeError.value = '验证码必须为6位数字'
|
|
} else {
|
|
smsCodeError.value = ''
|
|
}
|
|
}
|
|
|
|
// 显示/隐藏密码
|
|
const togglePassword = () => {
|
|
showPassword.value = !showPassword.value
|
|
}
|
|
|
|
// 切换记住密码
|
|
const toggleRemember = () => {
|
|
rememberMe.value = !rememberMe.value
|
|
console.log('记住密码:', rememberMe.value)
|
|
}
|
|
|
|
// 发送验证码
|
|
const sendSmsCode = () => {
|
|
onPhoneInput()
|
|
countdown.value = 60
|
|
smsBtnText.value = `${countdown.value}秒后重发`
|
|
countdownTimer.value = setInterval(() => {
|
|
countdown.value--
|
|
smsBtnText.value = `${countdown.value}秒后重发`
|
|
if (countdown.value <= 0) {
|
|
clearInterval(countdownTimer.value!)
|
|
countdownTimer.value = null
|
|
smsBtnText.value = '获取验证码'
|
|
}
|
|
}, 1000) as number
|
|
|
|
// 调用 wxchat 后端发送短信验证码
|
|
Api.auth.sendSmsCode(phoneNumber.value, 'login').then(response => {
|
|
console.log('验证码发送成功:', response)
|
|
uni.showToast({
|
|
title: '验证码已发送',
|
|
icon: 'success',
|
|
duration: 2000
|
|
})
|
|
}).catch(error => {
|
|
console.log('验证码发送失败:', error)
|
|
uni.showToast({
|
|
title: (error as any)?.message ?? '验证码发送失败',
|
|
icon: 'none'
|
|
})
|
|
})
|
|
|
|
}
|
|
// 保存登录凭证
|
|
const saveCredentials = () => {
|
|
try {
|
|
uni.setStorageSync('rememberedPhone', phoneNumber.value)
|
|
uni.setStorageSync('rememberedPassword', password.value)
|
|
console.log('登录凭证已保存')
|
|
} catch (e) {
|
|
console.error('保存登录凭证失败:', e)
|
|
}
|
|
}
|
|
// 密码登录(插件后端当前仅提供短信/一键登录,密码登录暂未开放)
|
|
const onLogin = () => {
|
|
if (!canLogin.value || loading.value) return
|
|
onPhoneInput()
|
|
onPasswordInput()
|
|
uni.showToast({ title: '密码登录暂未开放,请使用验证码登录', icon: 'none' })
|
|
}
|
|
|
|
// 验证码登录
|
|
const onSmsLogin = () => {
|
|
console.log('canSmsLogin', canSmsLogin.value)
|
|
if (!canSmsLogin.value || loading.value) return
|
|
onPhoneInput()
|
|
onSmsCodeInput()
|
|
loading.value = true
|
|
Api.auth.smsLogin(phoneNumber.value, smsCode.value, 'login').then((result : IUserInfo | null) => {
|
|
loading.value = false
|
|
if (result == null) {
|
|
uni.showToast({ title: '登录失败,请重试', icon: 'error' })
|
|
return
|
|
}
|
|
uni.showToast({ title: '登录成功', icon: 'success' })
|
|
uni.reLaunch({
|
|
url: "/pages/guide/guide"
|
|
})
|
|
}).catch((error : any) => {
|
|
loading.value = false
|
|
console.log(error)
|
|
uni.showToast({ title: error?.message ?? '登录失败', icon: 'none' })
|
|
})
|
|
}
|
|
|
|
// 一键登录(两步对接:先取本机号码预凭证,再换登录态)
|
|
const onQuickLogin = () => {
|
|
console.log('一键登录')
|
|
loading.value = true
|
|
Api.auth.getOneClickPreToken(phoneNumber.value).then((preRes : UTSJSONObject) => {
|
|
const preToken = preRes.getString('pre_token') ?? ''
|
|
if (preToken.length == 0) {
|
|
throw new Error('获取一键登录凭证失败')
|
|
}
|
|
return Api.auth.oneClickLogin(preToken)
|
|
}).then((response : UTSJSONObject) => {
|
|
loading.value = false
|
|
uni.showToast({ title: '登录成功', icon: 'success' })
|
|
setTimeout(() => {
|
|
uni.switchTab({ url: '/pages/index/index' })
|
|
}, 1200)
|
|
}).catch((error : any) => {
|
|
loading.value = false
|
|
console.log(error)
|
|
uni.showToast({ title: error?.message ?? '一键登录失败', icon: 'none' })
|
|
})
|
|
}
|
|
|
|
// 微信登录
|
|
const onWechatLogin = () => {
|
|
console.log('微信登录')
|
|
uni.showToast({
|
|
title: '微信登录',
|
|
icon: 'none',
|
|
duration: 1500
|
|
})
|
|
|
|
// 这里应该调用uni.login获取微信code
|
|
// uni.getProvider({
|
|
// service: 'oauth',
|
|
// success: (res) => {
|
|
// if (res.provider.includes('weixin')) {
|
|
// uni.login({
|
|
// provider: 'weixin',
|
|
// success: (loginRes) => {
|
|
// console.log('微信登录成功:', loginRes)
|
|
// }
|
|
// })
|
|
// }
|
|
// }
|
|
// })
|
|
}
|
|
|
|
// QQ登录
|
|
const onQQLogin = () => {
|
|
console.log('QQ登录')
|
|
uni.showToast({
|
|
title: 'QQ登录',
|
|
icon: 'none',
|
|
duration: 1500
|
|
})
|
|
}
|
|
|
|
// Apple登录
|
|
const onAppleLogin = () => {
|
|
console.log('Apple登录')
|
|
uni.showToast({
|
|
title: 'Apple登录',
|
|
icon: 'none',
|
|
duration: 1500
|
|
})
|
|
}
|
|
|
|
// 忘记密码
|
|
const forgotPassword = () => {
|
|
console.log('忘记密码')
|
|
uni.navigateTo({
|
|
url: '/pages/forgot-password/forgot-password'
|
|
})
|
|
}
|
|
|
|
// 注册
|
|
const goRegister = () => {
|
|
console.log('去注册')
|
|
uni.navigateTo({
|
|
url: '/pages/register/register'
|
|
})
|
|
}
|
|
|
|
// 返回
|
|
const goBack = () => {
|
|
uni.navigateBack()
|
|
}
|
|
|
|
// 显示用户协议
|
|
const showAgreement = () => {
|
|
showAgreementModal.value = true
|
|
}
|
|
|
|
// 显示隐私政策
|
|
const showPrivacy = () => {
|
|
uni.showModal({
|
|
title: '隐私政策',
|
|
content: '我们非常重视您的隐私保护,详细政策请查看完整版隐私政策。',
|
|
showCancel: false,
|
|
confirmText: '知道了'
|
|
})
|
|
}
|
|
|
|
// 关闭协议弹窗
|
|
const closeAgreementModal = () => {
|
|
showAgreementModal.value = false
|
|
}
|
|
|
|
// 显示区号选择器
|
|
const showAreaCodePicker = () => {
|
|
showAreaCodeModal.value = true
|
|
}
|
|
|
|
// 关闭区号选择器
|
|
const closeAreaCodePicker = () => {
|
|
showAreaCodeModal.value = false
|
|
}
|
|
|
|
// 选择区号
|
|
const selectAreaCode = (item : IAreaCodeItem) => {
|
|
areaCode.value = item.code
|
|
showAreaCodeModal.value = false
|
|
console.log('选择区号:', item)
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
/* 顶部装饰 */
|
|
.top-deco {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 300rpx;
|
|
overflow: hidden;
|
|
z-index: 0;
|
|
}
|
|
|
|
.deco-circle {
|
|
position: absolute;
|
|
border-radius: 50%;
|
|
background-color: #ffe9e4;
|
|
}
|
|
|
|
.circle-1 {
|
|
width: 300rpx;
|
|
height: 300rpx;
|
|
top: -150rpx;
|
|
right: -150rpx;
|
|
}
|
|
|
|
.circle-2 {
|
|
width: 200rpx;
|
|
height: 200rpx;
|
|
top: 50rpx;
|
|
left: -100rpx;
|
|
}
|
|
|
|
.circle-3 {
|
|
width: 150rpx;
|
|
height: 150rpx;
|
|
top: 150rpx;
|
|
right: 50rpx;
|
|
}
|
|
|
|
|
|
/* 应用Logo和标题 */
|
|
.app-header {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
margin-top: 120rpx;
|
|
margin-bottom: 60rpx;
|
|
z-index: 1;
|
|
}
|
|
|
|
.app-logo {
|
|
width: 150rpx;
|
|
height: 150rpx;
|
|
border-radius: 30rpx;
|
|
margin-bottom: 30rpx;
|
|
background-color: #ff8e53;
|
|
box-shadow: 0 10rpx 30rpx rgba(255, 107, 107, 0.3);
|
|
}
|
|
|
|
.app-name {
|
|
font-size: 48rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
|
|
.app-slogan {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 登录表单 */
|
|
.login-form {
|
|
padding: 0 60rpx;
|
|
z-index: 1;
|
|
}
|
|
|
|
.form-group {
|
|
width: 100%;
|
|
display: flex;
|
|
margin-bottom: 40rpx;
|
|
flex-flow: row nowrap;
|
|
}
|
|
|
|
.input-with-icon {
|
|
display: flex;
|
|
flex-direction: row;
|
|
width: 100%;
|
|
align-items: center;
|
|
flex-flow: row nowrap;
|
|
padding: 25rpx 30rpx;
|
|
background-color: #f8f8f8;
|
|
flex-grow: 1;
|
|
border-radius: 20rpx;
|
|
border: 2rpx solid #f0f0f0;
|
|
transition: border-color 0.3s ease;
|
|
}
|
|
|
|
.input-with-icon-active {
|
|
border-color: #FF6B6B;
|
|
}
|
|
|
|
.input-wrapper {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-flow: row;
|
|
align-items: center;
|
|
}
|
|
|
|
.area-code {
|
|
display: flex;
|
|
align-items: center;
|
|
flex-flow: row nowrap;
|
|
padding: 0 20rpx 0 0;
|
|
border-right: 2rpx solid #e0e0e0;
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.area-code-text {
|
|
color: #666;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
|
|
.form-input {
|
|
flex: 1;
|
|
height: 40rpx;
|
|
}
|
|
|
|
.eye-icon {
|
|
padding-left: 20rpx;
|
|
}
|
|
|
|
.error-msg {
|
|
font-size: 24rpx;
|
|
color: #FF3B30;
|
|
margin-top: 10rpx;
|
|
padding-left: 10rpx;
|
|
}
|
|
|
|
/* 表单选项 */
|
|
.form-options {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
flex-flow: row nowrap;
|
|
margin-bottom: 60rpx;
|
|
}
|
|
|
|
.remember-me {
|
|
display: flex;
|
|
align-items: center;
|
|
|
|
flex-flow: row nowrap;
|
|
}
|
|
|
|
.checkbox {
|
|
width: 36rpx;
|
|
height: 36rpx;
|
|
border-radius: 8rpx;
|
|
border: 2rpx solid #ccc;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.checkbox.checked {
|
|
background-color: #FF6B6B;
|
|
border-color: #FF6B6B;
|
|
}
|
|
|
|
.option-text {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.forgot-text {
|
|
font-size: 24rpx;
|
|
color: #FF6B6B;
|
|
}
|
|
|
|
/* 验证码按钮 */
|
|
.sms-btn {
|
|
background-color: #FF6B6B;
|
|
color: #fff;
|
|
border: none;
|
|
border-radius: 30rpx;
|
|
padding: 15rpx 30rpx;
|
|
font-size: 24rpx;
|
|
white-space: nowrap;
|
|
margin-left: 20rpx;
|
|
}
|
|
|
|
|
|
/* 登录按钮 */
|
|
.login-btn {
|
|
|
|
background: linear-gradient(to bottom left, #FF6B6B, #FF8E53);
|
|
color: #fff;
|
|
border: none;
|
|
border-radius: 50rpx;
|
|
padding: 30rpx 0;
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
text-align: center;
|
|
box-shadow: 0 10rpx 30rpx rgba(255, 107, 107, 0.3);
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.login-btn-txt {
|
|
text-align: center;
|
|
}
|
|
|
|
.disabled {
|
|
background: linear-gradient(to bottom right, #9c9c9c, #959595);
|
|
box-shadow: none;
|
|
opacity: 0.7;
|
|
}
|
|
|
|
|
|
.loading {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 一键登录 */
|
|
.quick-login {
|
|
padding: 0 60rpx;
|
|
z-index: 1;
|
|
}
|
|
|
|
.quick-login-tip {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
margin-bottom: 60rpx;
|
|
}
|
|
|
|
/* text:first-child {
|
|
font-size: 32rpx;
|
|
color: #333;
|
|
font-weight: bold;
|
|
margin-bottom: 10rpx;
|
|
} */
|
|
|
|
.tip-sub {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.quick-login-btn {
|
|
background-color: #3d6df2;
|
|
color: #fff;
|
|
border: none;
|
|
border-radius: 50rpx;
|
|
padding: 30rpx 0;
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
margin-bottom: 40rpx;
|
|
box-shadow: 0 10rpx 30rpx rgba(0, 122, 255, 0.3);
|
|
}
|
|
|
|
.quick-login-content {
|
|
display: flex;
|
|
justify-content: center;
|
|
flex-flow: row nowrap;
|
|
align-items: center;
|
|
|
|
}
|
|
|
|
.agreement {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-flow: row wrap;
|
|
}
|
|
|
|
.agreement-text {
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.agreement-link {
|
|
font-size: 24rpx;
|
|
color: #007AFF;
|
|
}
|
|
|
|
/* 第三方登录 */
|
|
.third-party-login {
|
|
margin-top: 80rpx;
|
|
padding: 0 60rpx;
|
|
z-index: 1;
|
|
}
|
|
|
|
.divider {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 60rpx;
|
|
}
|
|
|
|
.divider-line {
|
|
flex: 1;
|
|
height: 2rpx;
|
|
background-color: #eee;
|
|
}
|
|
|
|
.divider-text {
|
|
padding: 0 30rpx;
|
|
font-size: 24rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.third-party-buttons {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
flex-flow: row nowrap;
|
|
}
|
|
|
|
.third-party-btn {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
width: 120rpx;
|
|
}
|
|
|
|
.third-party-btn .uni-icons {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
box-shadow: 0 10rpx 20rpx rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.wechat .uni-icons {
|
|
background-color: #07C160;
|
|
}
|
|
|
|
.qq .uni-icons {
|
|
background-color: #12B7F5;
|
|
}
|
|
|
|
.apple .uni-icons {
|
|
background-color: #000;
|
|
}
|
|
|
|
.btn-text {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
}
|
|
|
|
/* 注册链接 */
|
|
.register-link {
|
|
position: absolute;
|
|
bottom: 120rpx;
|
|
left: 0;
|
|
right: 0;
|
|
display: flex;
|
|
flex-direction: row;
|
|
justify-content: center;
|
|
flex-flow: row nowrap;
|
|
align-items: center;
|
|
z-index: 1;
|
|
}
|
|
|
|
.register-link-text {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.register-text {
|
|
font-size: 24rpx;
|
|
color: #FF6B6B;
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* 协议弹窗 */
|
|
.agreement-modal,
|
|
.area-code-modal {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
z-index: 1000;
|
|
padding: 40rpx;
|
|
}
|
|
|
|
.modal-content {
|
|
width: 100%;
|
|
max-width: 600rpx;
|
|
background-color: #fff;
|
|
border-radius: 30rpx;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.modal-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 40rpx 30rpx 20rpx;
|
|
border-bottom: 2rpx solid #f0f0f0;
|
|
}
|
|
|
|
.modal-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
|
|
.modal-body {
|
|
flex: 1;
|
|
padding: 30rpx;
|
|
max-height: 500rpx;
|
|
}
|
|
|
|
.agreement-content {
|
|
font-size: 24rpx;
|
|
color: #666;
|
|
white-space: pre-wrap;
|
|
}
|
|
|
|
.modal-footer {
|
|
padding: 30rpx;
|
|
border-top: 2rpx solid #f0f0f0;
|
|
}
|
|
|
|
.modal-btn {
|
|
background-color: #ff7a63;
|
|
color: #fff;
|
|
border: none;
|
|
border-radius: 40rpx;
|
|
padding: 25rpx 0;
|
|
font-size: 28rpx;
|
|
font-weight: bold;
|
|
width: 100%;
|
|
}
|
|
|
|
/* 区号选择 */
|
|
.area-code-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx 0;
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
}
|
|
|
|
|
|
.area-code-item-last {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.area-code-item.active {
|
|
background-color: #fff5f5;
|
|
}
|
|
|
|
.country-name {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
}
|
|
|
|
.country-code {
|
|
font-size: 28rpx;
|
|
color: #666;
|
|
}
|
|
</style> |