You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
777 lines
16 KiB
777 lines
16 KiB
<template>
|
|
<view class="login-registration-container">
|
|
<!-- 自定义导航栏 -->
|
|
<view
|
|
class="custom-navbar"
|
|
:style="{ paddingTop: safeAreaInsets?.top + 'px' }"
|
|
>
|
|
<!-- <view class="nav-left">
|
|
<text class="back-btn" @click="goToIndex"><</text>
|
|
</view> -->
|
|
<view class="nav-right">
|
|
<image
|
|
class="icons"
|
|
src="../../../static/icons/Headset.png"
|
|
alt="联系客服"
|
|
/>
|
|
<image
|
|
class="icons"
|
|
@click="goToIndex"
|
|
src="../../../static/icons/Frame.png"
|
|
alt="返回首页"
|
|
/>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- Logo -->
|
|
<!-- <image class="logo" src="/static/logo.png" mode="aspectFit"></image> -->
|
|
|
|
<!-- 欢迎语 -->
|
|
<text class="welcome-text">登录DeepChart</text>
|
|
|
|
<!-- 邮箱/手机号切换 -->
|
|
<view class="switch-container">
|
|
<text
|
|
class="switch-item"
|
|
:class="{ active: switchType === 'User' }"
|
|
@click="switchUser"
|
|
>用户名</text
|
|
>
|
|
<text
|
|
class="switch-item"
|
|
:class="{ active: switchType === 'Phone' }"
|
|
@click="switchPhone"
|
|
>手机号</text
|
|
><text
|
|
class="switch-item"
|
|
:class="{ active: switchType === 'Email' }"
|
|
@click="switchEmail"
|
|
>邮箱</text
|
|
>
|
|
</view>
|
|
<!-- 输入框 -->
|
|
<view class="input-container">
|
|
<view v-if="switchType === 'User'">
|
|
<!-- 修改邮箱输入框容器,将图标包含在内 -->
|
|
<view class="input-with-icon">
|
|
<image
|
|
class="input-icon"
|
|
src="../../../static/icons/People-safe.png"
|
|
alt=""
|
|
/>
|
|
<input
|
|
class="input-field"
|
|
type="text"
|
|
placeholder="请输入DeepChart ID"
|
|
v-model="email"
|
|
/>
|
|
</view>
|
|
<view class="input-with-icon">
|
|
<image
|
|
class="input-icon"
|
|
src="../../../static/icons/Unlock.png"
|
|
alt=""
|
|
/>
|
|
<input
|
|
class="input-field"
|
|
type="text"
|
|
placeholder="请输入密码"
|
|
v-model="password"
|
|
/>
|
|
</view>
|
|
</view>
|
|
<view v-if="switchType === 'Email'">
|
|
<!-- 修改邮箱输入框容器,将图标包含在内 -->
|
|
<view class="input-with-icon">
|
|
<image
|
|
class="input-icon"
|
|
src="../../../static/icons/Mail.png"
|
|
alt=""
|
|
/>
|
|
<input
|
|
class="input-field"
|
|
type="text"
|
|
placeholder="请输入邮箱"
|
|
v-model="email"
|
|
/>
|
|
<view>
|
|
<button
|
|
class="send-code-btn-email"
|
|
:disabled="isCodeBtnDisabled"
|
|
:class="{ 'send-code-btn-disabled': isCodeBtnDisabled }"
|
|
@click="sendCode"
|
|
>
|
|
<text
|
|
class="send-code-text"
|
|
:class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }"
|
|
>{{ codeBtnText }}</text
|
|
>
|
|
</button>
|
|
</view>
|
|
</view>
|
|
<view class="input-with-icon">
|
|
<image
|
|
class="input-icon"
|
|
src="../../../static/icons/Text-recognition.png"
|
|
alt=""
|
|
/>
|
|
<input
|
|
class="input-field"
|
|
type="text"
|
|
placeholder="请输入验证码"
|
|
v-model="password"
|
|
/>
|
|
</view>
|
|
</view>
|
|
<view v-if="switchType === 'Phone'" class="phone-input-container">
|
|
<view class="country-code-selector" @click="showCountryPicker">
|
|
<image
|
|
class="country-flag-img"
|
|
src="../../../static/icons/Iphone.png"
|
|
mode="aspectFit"
|
|
></image>
|
|
<text class="country-code">{{ selectedCountry.code }}</text>
|
|
<!-- <text class="arrow-down">▼</text> -->
|
|
</view>
|
|
<input
|
|
class="input-field phone-input"
|
|
type="number"
|
|
placeholder="输入手机号"
|
|
v-model="phone"
|
|
@input="onPhoneInput"
|
|
/>
|
|
<view>
|
|
<button
|
|
class="send-code-btn"
|
|
:disabled="isCodeBtnDisabled"
|
|
:class="{ 'send-code-btn-disabled': isCodeBtnDisabled }"
|
|
@click="sendCode"
|
|
>
|
|
<text
|
|
class="send-code-text"
|
|
:class="{ 'send-code-btn-disabled-text': isCodeBtnDisabled }"
|
|
>{{ codeBtnText }}</text
|
|
>
|
|
</button>
|
|
</view>
|
|
</view>
|
|
<view v-if="switchType === 'Phone'" class="input-with-icon">
|
|
<image
|
|
class="input-icon"
|
|
src="../../../static/icons/Text-recognition.png"
|
|
alt=""
|
|
/>
|
|
<input
|
|
class="input-field"
|
|
type="text"
|
|
placeholder="请输入验证码"
|
|
v-model="password"
|
|
/>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 用户协议 -->
|
|
<view @click="changeCheckbox" class="agreement-container-one">
|
|
<image class="checkbox" :src="checkboxUrl"></image>
|
|
<text class="agreement-text-one"
|
|
>接受 <text class="link" @click="openAgreement">用户协议</text> 和
|
|
<text class="link" @click="openPrivacy">隐私政策</text></text
|
|
>
|
|
</view>
|
|
<view v-if="switchType === 'User'" class="agreement-container">
|
|
<text class="agreement-text"
|
|
><text @click="recoverPassword">忘记ID/密码</text>
|
|
</text>
|
|
</view>
|
|
<view v-else class="agreement-container">
|
|
<text class="agreement-text">
|
|
<!-- 添加占位元素,防止页面变形 -->
|
|
<text style="visibility: hidden">占位符</text>
|
|
</text>
|
|
</view>
|
|
|
|
<!-- 注册按钮 -->
|
|
<button class="register-btn" @click="register">登录</button>
|
|
|
|
<!-- 或者 -->
|
|
<text class="or-text" @click="goToRegistration"
|
|
>如果您还没有账号,点击注册 >
|
|
</text>
|
|
|
|
<!-- 第三方登录 -->
|
|
<view class="third-party-login">
|
|
<view class="third-party-btn" @click="loginWithApple">
|
|
<image
|
|
class="apple-icon"
|
|
src="../../../static/icons/appleIcons.png"
|
|
mode="aspectFit"
|
|
></image>
|
|
<text class="third-party-text">通过 Apple 登录 </text>
|
|
</view>
|
|
|
|
<view class="third-party-btn" @click="loginWithGoogle">
|
|
<image
|
|
class="google-icon"
|
|
src="../../../static/icons/GoogleIcons.png"
|
|
mode="aspectFit"
|
|
></image>
|
|
<text class="third-party-text">通过 Google 登录</text>
|
|
</view>
|
|
</view>
|
|
<footerBar class="static-footer" :type="type"></footerBar>
|
|
</view>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref } from "vue";
|
|
// 导入完整的国家列表
|
|
import countryList from "./list.js";
|
|
import footerBar from '../../../components/footerBar-cn'
|
|
|
|
const type = ref('member')
|
|
const email = ref("");
|
|
const password = ref("");
|
|
const phone = ref("");
|
|
const agreed = ref(false);
|
|
const switchType = ref("Email"); // 默认是邮箱注册
|
|
const { safeAreaInsets } = uni.getSystemInfoSync();
|
|
const codeBtnText = ref("获取验证码");
|
|
const isCodeBtnDisabled = ref(false); // 添加验证码按钮禁用状态
|
|
const checkboxUrl = ref("../../../static/icons/Check-one-false.png");
|
|
|
|
// 使用从list.js导入的完整国家列表数据
|
|
const countries = ref(
|
|
countryList.list.map((item) => ({
|
|
name: item.name,
|
|
code: `+${item.tel}`,
|
|
flag: item.flag,
|
|
short: item.short,
|
|
en: item.en,
|
|
}))
|
|
);
|
|
|
|
// 默认选中的国家(中国)
|
|
const selectedCountry = ref(
|
|
countries.value.find((country) => country.short === "CN") ||
|
|
countries.value[0]
|
|
);
|
|
|
|
// 显示国家选择器
|
|
function showCountryPicker() {
|
|
uni.showActionSheet({
|
|
itemList: countries.value.map(
|
|
(country) => `${country.name} ${country.code}`
|
|
),
|
|
success: function (res) {
|
|
selectedCountry.value = countries.value[res.tapIndex];
|
|
},
|
|
});
|
|
}
|
|
|
|
function goToIndex() {
|
|
// 返回上一页
|
|
uni.navigateTo({
|
|
url: "/pages/start/index/index",
|
|
});
|
|
}
|
|
|
|
function switchUser() {
|
|
// 切换到手机注册
|
|
switchType.value = "User";
|
|
}
|
|
|
|
function switchEmail() {
|
|
// 切换到邮箱注册
|
|
switchType.value = "Email";
|
|
}
|
|
|
|
function switchPhone() {
|
|
// 切换到手机注册
|
|
switchType.value = "Phone";
|
|
}
|
|
|
|
function register() {
|
|
if (switchType.value === "Email") {
|
|
// 登录逻辑
|
|
if (!email.value) {
|
|
uni.showToast({
|
|
title: "请输入邮箱地址",
|
|
icon: "none",
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 发送登录请求
|
|
console.log("登录:", email.value);
|
|
}
|
|
|
|
if (switchType.value === "Phone") {
|
|
// 登录逻辑
|
|
if (!phone.value) {
|
|
uni.showToast({
|
|
title: "请输入手机号码",
|
|
icon: "none",
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 发送登录请求
|
|
console.log("登录:", phone.value);
|
|
}
|
|
}
|
|
|
|
function loginWithApple() {
|
|
// Apple登录逻辑
|
|
console.log("通过Apple登录");
|
|
uni.login({
|
|
provider: "apple",
|
|
success: function (loginRes) {
|
|
// 登录成功
|
|
uni.getUserInfo({
|
|
provider: "apple",
|
|
success: function (info) {
|
|
console.log(info);
|
|
},
|
|
});
|
|
},
|
|
fail: function (err) {
|
|
// 登录授权失败
|
|
// err.code错误码参考`授权失败错误码(code)说明`
|
|
console.log(err);
|
|
},
|
|
});
|
|
}
|
|
|
|
function loginWithGoogle() {
|
|
// Google登录逻辑
|
|
console.log("通过Google登录");
|
|
uni.login({
|
|
provider: "google",
|
|
success: function (loginRes) {
|
|
// 登录成功
|
|
uni.getUserInfo({
|
|
provider: "google",
|
|
success: function (info) {
|
|
console.log(info);
|
|
},
|
|
});
|
|
},
|
|
fail: function (err) {
|
|
// 登录授权失败
|
|
// err.code是错误码
|
|
console.log(err);
|
|
},
|
|
});
|
|
}
|
|
|
|
function goToRegistration() {
|
|
// 跳转到登录页
|
|
uni.navigateTo({
|
|
url: "/pages/start/Registration/Registration",
|
|
});
|
|
}
|
|
|
|
function onPhoneInput(e) {
|
|
// 确保只允许输入数字
|
|
const value = e.detail.value;
|
|
// 使用 isNaN 检查是否为有效数字
|
|
if (isNaN(value)) {
|
|
phone.value = "";
|
|
} else {
|
|
phone.value = value;
|
|
}
|
|
}
|
|
|
|
function sendCode() {
|
|
// 如果按钮已禁用,则不执行后续逻辑
|
|
if (isCodeBtnDisabled.value) return;
|
|
|
|
// 设置按钮为禁用状态
|
|
isCodeBtnDisabled.value = true;
|
|
codeBtnText.value = "重新发送";
|
|
let time = 6;
|
|
const timer = setInterval(() => {
|
|
time--;
|
|
codeBtnText.value = "重新发送 " + time + "s";
|
|
if (time <= 0) {
|
|
clearInterval(timer);
|
|
codeBtnText.value = "重新发送";
|
|
// 倒计时结束后启用按钮
|
|
isCodeBtnDisabled.value = false;
|
|
}
|
|
}, 1000);
|
|
|
|
return;
|
|
}
|
|
|
|
function openAgreement() {
|
|
// 打开用户协议
|
|
console.log("打开用户协议");
|
|
uni.navigateTo({
|
|
url: "/pages/start/agreement/agreement",
|
|
});
|
|
}
|
|
|
|
function openPrivacy() {
|
|
// 打开隐私政策
|
|
console.log("打开隐私政策");
|
|
uni.navigateTo({
|
|
url: "/pages/start/privacy/privacy",
|
|
});
|
|
}
|
|
|
|
function recoverPassword() {
|
|
// 忘记密码
|
|
console.log("忘记密码");
|
|
}
|
|
|
|
function changeCheckbox() {
|
|
agreed.value = !agreed.value;
|
|
checkboxUrl.value = agreed.value
|
|
? "../../../static/icons/Check-one-true.png"
|
|
: "../../../static/icons/Check-one-false.png";
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.login-registration-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0 70rpx;
|
|
height: 100vh;
|
|
background-color: #ffffff;
|
|
}
|
|
|
|
/* 自定义导航栏样式 */
|
|
.custom-navbar {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
/* z-index: 999; */
|
|
width: 90%;
|
|
height: 80rpx;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 10rpx 40rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.nav-left,
|
|
.nav-right {
|
|
flex: 1;
|
|
}
|
|
|
|
.nav-right {
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.icons {
|
|
margin: 20rpx;
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
/* margin-right: 10rpx; */
|
|
}
|
|
|
|
.back-btn,
|
|
.headphone-btn {
|
|
font-size: 36rpx;
|
|
font-weight: bold;
|
|
color: #333333;
|
|
padding: 10rpx;
|
|
}
|
|
|
|
.logo {
|
|
width: 120rpx;
|
|
height: 120rpx;
|
|
margin-bottom: 60rpx;
|
|
border-radius: 20%;
|
|
}
|
|
|
|
.welcome-text {
|
|
font-size: 48rpx;
|
|
font-weight: bold;
|
|
color: #333333;
|
|
margin-bottom: 60rpx;
|
|
/* text-align: left; */
|
|
/* align-self: flex-start; */
|
|
}
|
|
|
|
.switch-container {
|
|
display: flex;
|
|
margin-bottom: 40rpx;
|
|
align-self: flex-start;
|
|
}
|
|
|
|
.switch-item {
|
|
font-size: 28rpx;
|
|
color: #999999;
|
|
padding: 10rpx 20rpx;
|
|
position: relative;
|
|
}
|
|
|
|
.switch-item::after {
|
|
content: "";
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 60%;
|
|
/* 控制边框宽度 */
|
|
height: 2rpx;
|
|
background-color: transparent;
|
|
}
|
|
|
|
.switch-item.active {
|
|
color: #333333;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.switch-item.active::after {
|
|
content: "";
|
|
position: absolute;
|
|
top: 60rpx;
|
|
bottom: 0;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
width: 30%;
|
|
/* 控制边框宽度 */
|
|
height: 7rpx;
|
|
background-color: #333333;
|
|
}
|
|
|
|
.input-container {
|
|
width: 100%;
|
|
}
|
|
|
|
/* 添加图标输入框样式 */
|
|
.input-with-icon {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 100%;
|
|
height: 80rpx;
|
|
border-bottom: 2rpx solid #e5e5e5;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.input-icon {
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
margin: 0 20rpx;
|
|
}
|
|
|
|
.input-field {
|
|
flex: 1;
|
|
height: 80rpx;
|
|
padding: 15rpx 0;
|
|
font-size: 28rpx;
|
|
color: #333333;
|
|
border: none;
|
|
background-color: transparent;
|
|
}
|
|
|
|
.phone-input-container {
|
|
display: flex;
|
|
align-items: center;
|
|
width: 95.8%;
|
|
height: 80rpx;
|
|
/* border-radius: 20rpx; */
|
|
/* border: 2rpx solid #e5e5e5; */
|
|
/* background-color: #f5f5f5; */
|
|
padding: 0 10rpx;
|
|
border-bottom: 2rpx solid #e5e5e5;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.country-code-selector {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0 10rpx;
|
|
padding-bottom: 1rpx;
|
|
height: 100%;
|
|
/* border-right: 2rpx solid #e5e5e5; */
|
|
/* background-color: #f5f5f5; */
|
|
border-radius: 20rpx 0 0 20rpx;
|
|
}
|
|
|
|
.country-code {
|
|
font-size: 28rpx;
|
|
color: #333333;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.country-flag-img {
|
|
width: 40rpx;
|
|
height: 40rpx;
|
|
margin-right: 10rpx;
|
|
}
|
|
|
|
.arrow-down {
|
|
font-size: 20rpx;
|
|
color: #999999;
|
|
}
|
|
|
|
.phone-input {
|
|
flex: 1;
|
|
width: auto;
|
|
height: 100%;
|
|
border: none;
|
|
background-color: transparent;
|
|
padding: 0 0rpx;
|
|
}
|
|
|
|
.send-code-btn {
|
|
width: 200rpx;
|
|
height: 60rpx;
|
|
display: inline-flex;
|
|
padding: 0rpx 10rpx;
|
|
justify-content: center;
|
|
align-items: center;
|
|
gap: 10px;
|
|
border-radius: 4px;
|
|
background: #000;
|
|
}
|
|
.send-code-btn-email {
|
|
width: 200rpx;
|
|
height: 60rpx;
|
|
display: inline-flex;
|
|
padding: 0rpx 10rpx;
|
|
justify-content: center;
|
|
align-items: center;
|
|
gap: 10px;
|
|
border-radius: 4px;
|
|
background: #000;
|
|
margin-right: 15rpx;
|
|
}
|
|
|
|
.send-code-btn-disabled {
|
|
background: #e6e6e6;
|
|
/* 禁用状态下的灰色背景 */
|
|
}
|
|
|
|
.send-code-btn-disabled-text {
|
|
color: #999999 !important;
|
|
}
|
|
|
|
.send-code-text {
|
|
color: #fff;
|
|
font-size: 28rpx;
|
|
}
|
|
|
|
.agreement-container-one {
|
|
display: flex;
|
|
align-items: center;
|
|
align-self: flex-start;
|
|
margin-bottom: 80rpx;
|
|
}
|
|
|
|
.agreement-container {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 30rpx;
|
|
margin-top: -60rpx;
|
|
align-self: flex-start;
|
|
}
|
|
|
|
.checkbox {
|
|
width: 30rpx;
|
|
height: 30rpx;
|
|
margin-left: 20rpx;
|
|
/* flex: content; */
|
|
}
|
|
|
|
.agreement-text-one {
|
|
font-size: 22rpx;
|
|
color: #666666;
|
|
text-align: center;
|
|
margin-left: 10rpx;
|
|
}
|
|
|
|
.agreement-text {
|
|
margin-left: 20rpx;
|
|
font-size: 24rpx;
|
|
color: #666666;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.link {
|
|
color: #333333;
|
|
font-weight: bold;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.register-btn {
|
|
width: 100%;
|
|
height: 80rpx;
|
|
background-color: #000000;
|
|
color: white;
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
border-radius: 40rpx;
|
|
margin-bottom: 40rpx;
|
|
}
|
|
|
|
.or-text {
|
|
font-size: 24rpx;
|
|
color: #999999;
|
|
margin-bottom: 40rpx;
|
|
}
|
|
|
|
.third-party-login {
|
|
width: 100%;
|
|
margin-bottom: 60rpx;
|
|
}
|
|
|
|
.third-party-text {
|
|
color: #ffffff;
|
|
font-weight: bold;
|
|
white-space: pre;
|
|
}
|
|
|
|
.third-party-btn {
|
|
width: 100%;
|
|
height: 80rpx;
|
|
background-color: rgb(0, 0, 0);
|
|
border: 2rpx solid #e5e5e5;
|
|
border-radius: 40rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-bottom: 20rpx;
|
|
font-size: 28rpx;
|
|
color: #333333;
|
|
}
|
|
|
|
.google-icon,
|
|
.apple-icon {
|
|
width: 60rpx;
|
|
height: 60rpx;
|
|
margin-right: 20rpx;
|
|
}
|
|
|
|
.existing-account {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.account-text {
|
|
font-size: 24rpx;
|
|
color: #666666;
|
|
}
|
|
|
|
.login-link {
|
|
font-size: 24rpx;
|
|
font-weight: bold;
|
|
color: #333333;
|
|
margin-left: 10rpx;
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.static-footer {
|
|
position: fixed;
|
|
bottom: 0;
|
|
}
|
|
</style>
|