Files
integral-shop/single_uniapp22miao/pages/sub-pages/login/register.vue

424 lines
9.5 KiB
Vue
Raw Normal View History

<template>
<view class="register-page">
<view class="container">
<view class="title">创建您的账号</view>
<view class="subtitle">已有账号<text class="link" @click="goToLogin">立即登录</text></view>
<!-- 注册表单 -->
<view class="form-container">
<!-- 手机号 -->
<view class="form-item">
<view class="form-label">
<text class="icon">📱</text>
<text>手机号</text>
</view>
<input
v-model="formData.mobile"
type="number"
maxlength="11"
placeholder="请输入您的手机号"
class="form-input"
/>
</view>
<!-- 验证码 -->
<view class="form-item">
<view class="form-label">
<text class="icon"></text>
<text>验证码</text>
</view>
<view class="code-input-wrapper">
<input
v-model="formData.code"
type="number"
maxlength="6"
placeholder="请输入验证码"
class="form-input"
/>
<button
class="send-code-btn"
:class="{ 'disabled': countdown > 0 }"
:disabled="countdown > 0 || !canSendCode"
@click="sendCode"
>
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
</button>
</view>
</view>
<!-- 密码 -->
<view class="form-item">
<view class="form-label">
<text class="icon">🔒</text>
<text>登录密码</text>
</view>
<input
v-model="formData.password"
:password="!showPassword"
placeholder="请输入登录密码(必填)"
class="form-input"
/>
<view class="eye-icon" @click="togglePassword">
<text>{{ showPassword ? '👁️' : '👁️‍🗨️' }}</text>
</view>
</view>
<!-- 邀请码 -->
<view class="form-item">
<view class="form-label">
<text class="icon">🎁</text>
<text>邀请码选填</text>
</view>
<input
v-model="formData.inviteCode"
placeholder="请输入邀请码"
class="form-input"
/>
</view>
<!-- 同意协议 -->
<view class="agreement">
<checkbox-group @change="onAgreeChange">
<label class="checkbox-label">
<checkbox value="agree" :checked="agreed" color="#FF4757" />
<text>同意</text>
<text class="link" @click.stop="viewAgreement('user')">用户协议</text>
<text></text>
<text class="link" @click.stop="viewAgreement('privacy')">购买委托代卖协议</text>
</label>
</checkbox-group>
</view>
<!-- 注册按钮 -->
<button
class="register-btn"
:class="{ 'disabled': !canRegister }"
:disabled="!canRegister"
:loading="registering"
@click="handleRegister"
>
注册
</button>
</view>
</view>
</view>
</template>
<script>
import { userRegister, sendSms } from '@/api/miao.js';
export default {
data() {
return {
formData: {
mobile: '',
code: '',
password: '',
inviteCode: ''
},
showPassword: false,
agreed: false,
countdown: 0,
registering: false,
timer: null
}
},
computed: {
canSendCode() {
return this.formData.mobile.length === 11;
},
canRegister() {
return this.formData.mobile.length === 11 &&
this.formData.code.length === 6 &&
this.formData.password.length >= 6 &&
this.agreed;
}
},
onUnload() {
if (this.timer) {
clearInterval(this.timer);
}
},
methods: {
// 切换密码显示
togglePassword() {
this.showPassword = !this.showPassword;
},
// 验证手机号
validateMobile(mobile) {
const reg = /^1[3-9]\d{9}$/;
return reg.test(mobile);
},
// 发送验证码
async sendCode() {
if (!this.validateMobile(this.formData.mobile)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
try {
const res = await sendSms({
mobile: this.formData.mobile,
event: 'register'
});
if (res.code === 0) {
uni.showToast({
title: '验证码已发送',
icon: 'success'
});
// 开始倒计时
this.countdown = 60;
this.timer = setInterval(() => {
this.countdown--;
if (this.countdown <= 0) {
clearInterval(this.timer);
}
}, 1000);
} else {
uni.showToast({
title: res.msg || '发送失败',
icon: 'none'
});
}
} catch (error) {
console.error('发送验证码失败:', error);
uni.showToast({
title: error.msg || '发送失败',
icon: 'none'
});
}
},
// 同意协议变化
onAgreeChange(e) {
this.agreed = e.detail.value.length > 0;
},
// 查看协议
viewAgreement(type) {
uni.navigateTo({
url: `/pages/sub-pages/agreement/index?type=${type}`
});
},
// 注册
async handleRegister() {
if (!this.validateMobile(this.formData.mobile)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
if (this.formData.password.length < 6) {
uni.showToast({
title: '密码长度不能少于6位',
icon: 'none'
});
return;
}
if (!this.agreed) {
uni.showToast({
title: '请先同意用户协议',
icon: 'none'
});
return;
}
this.registering = true;
try {
const res = await userRegister({
mobile: this.formData.mobile,
code: this.formData.code,
password: this.formData.password,
invite_code: this.formData.inviteCode
});
if (res.code === 0) {
uni.showToast({
title: '注册成功',
icon: 'success'
});
// 保存token
if (res.data.token) {
uni.setStorageSync('token', res.data.token);
uni.setStorageSync('userInfo', res.data.user_info);
}
// 跳转到首页或登录页
setTimeout(() => {
uni.switchTab({
url: '/pages/index/index'
});
}, 1500);
} else {
uni.showToast({
title: res.msg || '注册失败',
icon: 'none'
});
}
} catch (error) {
console.error('注册失败:', error);
uni.showToast({
title: error.msg || '注册失败,请重试',
icon: 'none'
});
} finally {
this.registering = false;
}
},
// 去登录页
goToLogin() {
uni.navigateBack();
}
}
}
</script>
<style lang="scss" scoped>
.register-page {
min-height: 100vh;
background-color: #f5f5f5;
}
.container {
padding: 40rpx 30rpx;
.title {
font-size: 48rpx;
font-weight: bold;
color: #333;
margin-bottom: 10rpx;
}
.subtitle {
font-size: 26rpx;
color: #666;
margin-bottom: 60rpx;
.link {
color: #FF4757;
}
}
}
.form-container {
background-color: #fff;
border-radius: 20rpx;
padding: 40rpx 30rpx;
.form-item {
margin-bottom: 40rpx;
.form-label {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.icon {
font-size: 28rpx;
margin-right: 10rpx;
}
text {
font-size: 28rpx;
color: #333;
}
}
.form-input {
height: 80rpx;
padding: 0 20rpx;
background-color: #f5f5f5;
border-radius: 40rpx;
font-size: 28rpx;
}
.code-input-wrapper {
display: flex;
align-items: center;
.form-input {
flex: 1;
margin-right: 15rpx;
}
.send-code-btn {
width: 180rpx;
height: 80rpx;
line-height: 80rpx;
background-color: #FF4757;
color: #fff;
border-radius: 40rpx;
font-size: 24rpx;
border: none;
&.disabled {
background-color: #ccc;
}
}
}
.eye-icon {
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
font-size: 32rpx;
}
}
.agreement {
margin-bottom: 40rpx;
.checkbox-label {
display: flex;
align-items: center;
font-size: 24rpx;
color: #666;
checkbox {
margin-right: 10rpx;
}
.link {
color: #FF4757;
}
}
}
.register-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
background: linear-gradient(90deg, #FF6B6B, #FF4757);
color: #fff;
border-radius: 45rpx;
font-size: 32rpx;
font-weight: bold;
border: none;
&.disabled {
opacity: 0.6;
}
}
}
</style>