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.
 
 
 
 
 

509 lines
9.9 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">
<text class="headphone-btn">🎧</text>
</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 === 'Email' }"
@click="switchEmail"
>邮箱/用户名</text
>
<text
class="switch-item"
:class="{ active: switchType === 'Phone' }"
@click="switchPhone"
>手机号</text
>
</view>
<!-- 输入框 -->
<view class="input-container">
<input
v-if="switchType === 'Email'"
class="input-field"
type="text"
placeholder="输入邮箱/用户名"
v-model="email"
/>
<view v-else class="phone-input-container">
<view class="country-code-selector" @click="showCountryPicker">
<image
class="country-flag-img"
:src="selectedCountry.flag"
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>
</view>
<!-- 注册按钮 -->
<button class="register-btn" @click="register">下一步</button>
<!-- 或者 -->
<text class="or-text">或者</text>
<!-- 第三方登录 -->
<view class="third-party-login">
<view class="third-party-btn" @click="loginWithApple">
<image
class="apple-icon"
src="/static/apple-icon.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/google-icon.png"
mode="aspectFit"
></image>
<text class="third-party-text">通过 Google 继续</text>
</view>
</view>
<!-- 已有账号 -->
<view class="existing-account">
<text class="account-text">未注册账号?</text>
<text class="login-link" @click="goToRegistration">注册</text>
</view>
</view>
</template>
<script setup>
import { ref } from "vue";
// 导入完整的国家列表
import countryList from "./list.js";
const email = ref("");
const phone = ref("");
const agreed = ref(false);
const switchType = ref("Email"); // 默认是邮箱注册
const { safeAreaInsets } = uni.getSystemInfoSync();
// 使用从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 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) {
// 获取用户信息成功, info.authResult中保存登录认证数据
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) {
// 获取用户信息成功, info.authResult保存用户信息
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;
}
}
</script>
<style scoped>
.login-registration-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 40rpx;
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;
}
.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%;
margin-bottom: 40rpx;
}
.input-field {
width: 90%;
height: 80rpx;
border-radius: 20rpx;
border: 2rpx solid #e5e5e5;
padding: 0 30rpx;
font-size: 28rpx;
color: #333333;
background-color: #f5f5f5;
}
.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;
}
.country-code-selector {
display: flex;
align-items: center;
padding: 0 20rpx;
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 20rpx;
}
.agreement-container {
/* display: flex; */
align-items: center;
margin-bottom: 40rpx;
align-self: flex-start;
}
.checkbox {
width: 10rpx;
height: 10rpx;
margin-right: 30rpx;
/* flex: content; */
}
.agreement-text {
margin-left: 20rpx;
font-size: 24rpx;
color: #666666;
}
.link {
color: #333333;
font-weight: bold;
text-decoration: underline;
}
.register-btn {
width: 100%;
height: 80rpx;
background-color: #333333;
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 {
font-weight: bold;
}
.third-party-btn {
width: 100%;
height: 80rpx;
background-color: white;
border: 2rpx solid #e5e5e5;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 20rpx;
font-size: 28rpx;
color: #333333;
}
.apple-icon {
width: 30rpx;
height: 30rpx;
margin-right: 20rpx;
}
.google-icon {
width: 30rpx;
height: 30rpx;
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;
}
</style>