Files
cunkebao_v3/Store_vue/components/LoginRegister.vue
2025-04-09 09:34:27 +08:00

374 lines
8.2 KiB
Vue

<template>
<view class="login-container" v-if="show" style="margin-top: var(--status-bar-height);">
<view class="login-wrapper">
<!-- 标签切换 -->
<u-tabs
:list="tabList"
:current="currentTab === 'verification' ? 0 : 1"
@change="tabChange"
:is-scroll="false"
inactive-color="#666"
active-color="#333"
item-style="height: 45px;"
bg-color="#f5f7fa"
></u-tabs>
<!-- 提示文本 -->
<view class="tip-text">
您所在地区仅支持 手机号 / 微信 / Apple 登录
</view>
<!-- 手机号输入 -->
<u-input
v-model="phoneNumber"
:clearable="true"
type="number"
placeholder="手机号"
prefixIcon="phone"
:border="true"
maxlength="11"
>
<template slot="prefix">
<text style="margin-right: 10px; color: #333; padding-right: 10px; border-right: 1px solid #eee">+86</text>
</template>
</u-input>
<!-- 验证码或密码输入 -->
<view v-if="currentTab === 'verification'" style="margin-top: 15px;">
<u-input
v-model="verificationCode"
:clearable="true"
type="number"
placeholder="验证码"
:border="true"
maxlength="6"
>
<template slot="suffix">
<u-button
size="mini"
:text="codeSending ? `${countDown}秒后重发` : '发送验证码'"
type="primary"
:disabled="codeSending || !phoneNumber || phoneNumber.length !== 11"
@click="sendVerificationCode"
style="margin-left: 5px; min-width: 100px;"
></u-button>
</template>
</u-input>
</view>
<view v-if="currentTab === 'password'" style="margin-top: 15px;">
<u-input
v-model="password"
type="password"
:password="!showPassword"
placeholder="密码"
:border="true"
>
<template slot="suffix">
<u-icon
:name="showPassword ? 'eye-fill' : 'eye-off'"
size="22"
color="#c0c4cc"
@click="showPassword = !showPassword"
></u-icon>
</template>
</u-input>
</view>
<!-- 用户协议 -->
<view class="agreement-container">
<u-checkbox
v-model="agreedTerms"
shape="circle"
active-color="#4080ff"
></u-checkbox>
<text class="agreement-text">已阅读并同意</text>
<text class="agreement-link" @tap="openProtocol">用户协议</text>
<text class="agreement-text"></text>
<text class="agreement-link" @tap="openPrivacy">隐私政策</text>
</view>
<!-- 登录按钮 -->
<u-button
text="登录"
type="primary"
shape="circle"
:disabled="!isFormValid"
@click="handleLogin"
:custom-style="{marginTop: '20px', marginBottom: '25px'}"
></u-button>
<!-- 分隔线 -->
<u-divider text="或" :hairline="true"></u-divider>
<!-- 第三方登录 -->
<view class="third-party-login">
<u-button
text="使用微信登录"
shape="circle"
@click="handleWechatLogin"
:ripple="true"
:custom-style="{backgroundColor: '#07c160', color: '#ffffff', marginBottom: '15px'}"
>
<template slot="default">
<u-icon name="weixin-fill" color="#ffffff" size="18" style="margin-right: 5px;"></u-icon>
<text>使用微信登录</text>
</template>
</u-button>
<u-button
text="使用 Apple 登录"
shape="circle"
@click="handleAppleLogin"
:ripple="true"
:custom-style="{backgroundColor: '#000000', color: '#ffffff'}"
>
<template slot="default">
<u-icon name="apple-fill" color="#ffffff" size="18" style="margin-right: 5px;"></u-icon>
<text>使用 Apple 登录</text>
</template>
</u-button>
</view>
<!-- 联系我们 -->
<view class="contact-us" @tap="handleContact">
联系我们
</view>
</view>
</view>
</template>
<script>
export default {
name: 'LoginRegister',
props: {
show: {
type: Boolean,
default: false
}
},
data() {
return {
tabList: [{name: '验证码登录'}, {name: '密码登录'}],
currentTab: 'verification', // verification 或 password
phoneNumber: '',
verificationCode: '',
password: '',
showPassword: false,
agreedTerms: false,
codeSending: false,
countDown: 60
}
},
computed: {
isFormValid() {
const phoneValid = this.phoneNumber && this.phoneNumber.length === 11;
if (this.currentTab === 'verification') {
return phoneValid && this.verificationCode && this.agreedTerms;
} else {
return phoneValid && this.password && this.agreedTerms;
}
}
},
methods: {
tabChange(index) {
this.currentTab = index === 0 ? 'verification' : 'password';
},
openProtocol() {
uni.showToast({
title: '打开用户协议',
icon: 'none'
});
},
openPrivacy() {
uni.showToast({
title: '打开隐私政策',
icon: 'none'
});
},
sendVerificationCode() {
if (this.codeSending) return;
if (!this.phoneNumber || this.phoneNumber.length !== 11) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
this.codeSending = true;
this.countDown = 60;
// 模拟发送验证码
uni.showToast({
title: '验证码已发送',
icon: 'success'
});
// 倒计时
const timer = setInterval(() => {
this.countDown--;
if (this.countDown <= 0) {
clearInterval(timer);
this.codeSending = false;
}
}, 1000);
},
handleLogin() {
if (!this.isFormValid) return;
// 验证手机号格式
if (!/^1\d{10}$/.test(this.phoneNumber)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
// 根据当前登录方式验证
if (this.currentTab === 'verification') {
if (!this.verificationCode || this.verificationCode.length !== 6) {
uni.showToast({
title: '请输入6位验证码',
icon: 'none'
});
return;
}
} else {
if (!this.password || this.password.length < 6) {
uni.showToast({
title: '密码不能少于6位',
icon: 'none'
});
return;
}
}
// 模拟登录过程
uni.showLoading({
title: '登录中...'
});
setTimeout(() => {
uni.hideLoading();
uni.showToast({
title: '登录成功',
icon: 'success',
duration: 1500,
success: () => {
// 登录成功后关闭登录页
setTimeout(() => {
this.$emit('close');
// 模拟返回用户信息
const userInfo = {
id: '123456',
nickname: '用户_' + Math.floor(Math.random() * 10000),
phone: this.phoneNumber,
avatar: ''
};
this.$emit('login-success', userInfo);
}, 1500);
}
});
}, 1500);
},
handleWechatLogin() {
uni.showToast({
title: '微信登录功能暂未实现',
icon: 'none'
});
},
handleAppleLogin() {
uni.showToast({
title: 'Apple登录功能暂未实现',
icon: 'none'
});
},
handleContact() {
uni.showToast({
title: '联系方式: support@example.com',
icon: 'none'
});
}
}
}
</script>
<style lang="scss">
.login-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 10001;
display: flex;
justify-content: center;
align-items: center;
}
.login-wrapper {
width: 100%;
height: 100%;
background-color: #fff;
border-radius: 0;
padding: 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
animation: slideInFromBottom 0.3s ease;
}
@keyframes slideInFromBottom {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
.tip-text {
font-size: 14px;
color: #666;
margin: 15px 0 20px;
line-height: 1.5;
}
.agreement-container {
display: flex;
align-items: center;
margin-top: 15px;
}
.agreement-text {
font-size: 12px;
color: #999;
margin-left: 5px;
}
.agreement-link {
font-size: 12px;
color: #4080ff;
margin: 0 4px;
}
.third-party-login {
display: flex;
flex-direction: column;
margin: 20px 0 30px;
}
.contact-us {
text-align: center;
color: #666;
font-size: 14px;
margin-top: auto;
padding: 15px 0;
}
</style>